Consumed.h revision c55bee6e278d888d7a5d29fc17df6a9ae1e8b7d3
1//===- Consumed.h ----------------------------------------------*- C++ --*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// A intra-procedural analysis for checking consumed properties.  This is based,
11// in part, on research on linear types.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_CONSUMED_H
16#define LLVM_CLANG_CONSUMED_H
17
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/ExprCXX.h"
20#include "clang/AST/StmtCXX.h"
21#include "clang/Analysis/AnalysisContext.h"
22#include "clang/Analysis/Analyses/PostOrderCFGView.h"
23#include "clang/Basic/SourceLocation.h"
24
25namespace clang {
26namespace consumed {
27
28  class ConsumedStmtVisitor;
29
30  typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
31  typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
32  typedef std::list<DelayedDiag> DiagList;
33
34  class ConsumedWarningsHandlerBase {
35
36  public:
37
38    virtual ~ConsumedWarningsHandlerBase();
39
40    /// \brief Emit the warnings and notes left by the analysis.
41    virtual void emitDiagnostics() {}
42
43    /// \brief Warn about unnecessary-test errors.
44    /// \param VariableName -- The name of the variable that holds the unique
45    /// value.
46    ///
47    /// \param Loc -- The SourceLocation of the unnecessary test.
48    virtual void warnUnnecessaryTest(StringRef VariableName,
49                                     StringRef VariableState,
50                                     SourceLocation Loc) {}
51
52    /// \brief Warn about use-while-consumed errors.
53    /// \param MethodName -- The name of the method that was incorrectly
54    /// invoked.
55    ///
56    /// \param Loc -- The SourceLocation of the method invocation.
57    virtual void warnUseOfTempWhileConsumed(StringRef MethodName,
58                                            SourceLocation Loc) {}
59
60    /// \brief Warn about use-in-unknown-state errors.
61    /// \param MethodName -- The name of the method that was incorrectly
62    /// invoked.
63    ///
64    /// \param Loc -- The SourceLocation of the method invocation.
65    virtual void warnUseOfTempInUnknownState(StringRef MethodName,
66                                             SourceLocation Loc) {}
67
68    /// \brief Warn about use-while-consumed errors.
69    /// \param MethodName -- The name of the method that was incorrectly
70    /// invoked.
71    ///
72    /// \param VariableName -- The name of the variable that holds the unique
73    /// value.
74    ///
75    /// \param Loc -- The SourceLocation of the method invocation.
76    virtual void warnUseWhileConsumed(StringRef MethodName,
77                                      StringRef VariableName,
78                                      SourceLocation Loc) {}
79
80    /// \brief Warn about use-in-unknown-state errors.
81    /// \param MethodName -- The name of the method that was incorrectly
82    /// invoked.
83    ///
84    /// \param VariableName -- The name of the variable that holds the unique
85    /// value.
86    ///
87    /// \param Loc -- The SourceLocation of the method invocation.
88    virtual void warnUseInUnknownState(StringRef MethodName,
89                                       StringRef VariableName,
90                                       SourceLocation Loc) {}
91  };
92
93  enum ConsumedState {
94    // No state information for the given variable.
95    CS_None,
96
97    CS_Unknown,
98    CS_Unconsumed,
99    CS_Consumed
100  };
101
102  class ConsumedStateMap {
103
104    typedef llvm::DenseMap<const VarDecl *, ConsumedState> MapType;
105    typedef std::pair<const VarDecl *, ConsumedState> PairType;
106
107  protected:
108
109    bool Reachable;
110    const Stmt *From;
111    MapType Map;
112
113  public:
114    ConsumedStateMap() : Reachable(true), From(NULL) {}
115    ConsumedStateMap(const ConsumedStateMap &Other)
116      : Reachable(Other.Reachable), From(Other.From), Map(Other.Map) {}
117
118    /// \brief Get the consumed state of a given variable.
119    ConsumedState getState(const VarDecl *Var);
120
121    /// \brief Merge this state map with another map.
122    void intersect(const ConsumedStateMap *Other);
123
124    /// \brief Return true if this block is reachable.
125    bool isReachable() const { return Reachable; }
126
127    /// \brief Mark all variables as unknown.
128    void makeUnknown();
129
130    /// \brief Mark the block as unreachable.
131    void markUnreachable();
132
133    /// \brief Set the source for a decision about the branching of states.
134    /// \param Source -- The statement that was the origin of a branching
135    /// decision.
136    void setSource(const Stmt *Source) { this->From = Source; }
137
138    /// \brief Set the consumed state of a given variable.
139    void setState(const VarDecl *Var, ConsumedState State);
140
141    /// \brief Remove the variable from our state map.
142    void remove(const VarDecl *Var);
143  };
144
145  class ConsumedBlockInfo {
146
147    ConsumedStateMap **StateMapsArray;
148    PostOrderCFGView::CFGBlockSet VisitedBlocks;
149
150  public:
151
152    ConsumedBlockInfo() : StateMapsArray(NULL) {}
153
154    ConsumedBlockInfo(const CFG *CFGraph)
155      : StateMapsArray(new ConsumedStateMap*[CFGraph->getNumBlockIDs()]()),
156        VisitedBlocks(CFGraph) {}
157
158    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap,
159                 bool &AlreadyOwned);
160    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap);
161
162    ConsumedStateMap* getInfo(const CFGBlock *Block);
163
164    void markVisited(const CFGBlock *Block);
165  };
166
167  /// A class that handles the analysis of uniqueness violations.
168  class ConsumedAnalyzer {
169
170    ConsumedBlockInfo BlockInfo;
171    ConsumedStateMap *CurrStates;
172
173    bool hasConsumableAttributes(const CXXRecordDecl *RD);
174    bool splitState(const CFGBlock *CurrBlock,
175                    const ConsumedStmtVisitor &Visitor);
176
177  public:
178
179    ConsumedWarningsHandlerBase &WarningsHandler;
180
181    ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
182        : WarningsHandler(WarningsHandler) {}
183
184    /// \brief Check a function's CFG for consumed violations.
185    ///
186    /// We traverse the blocks in the CFG, keeping track of the state of each
187    /// value who's type has uniquness annotations.  If methods are invoked in
188    /// the wrong state a warning is issued.  Each block in the CFG is traversed
189    /// exactly once.
190    void run(AnalysisDeclContext &AC);
191  };
192}} // end namespace clang::consumed
193
194#endif
195