1 //===- Consumed.h ----------------------------------------------*- C++ --*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // A intra-procedural analysis for checking consumed properties. This is based,
11 // in part, on research on linear types.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_CONSUMED_H
16 #define LLVM_CLANG_CONSUMED_H
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"
29 // No state information for the given variable.
37 class ConsumedStmtVisitor;
39 typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
40 typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
41 typedef std::list<DelayedDiag> DiagList;
43 class ConsumedWarningsHandlerBase {
47 virtual ~ConsumedWarningsHandlerBase();
49 /// \brief Emit the warnings and notes left by the analysis.
50 virtual void emitDiagnostics() {}
52 /// \brief Warn that a variable's state doesn't match at the entry and exit
55 /// \param Loc -- The location of the end of the loop.
57 /// \param VariableName -- The name of the variable that has a mismatched
59 virtual void warnLoopStateMismatch(SourceLocation Loc,
60 StringRef VariableName) {}
62 /// \brief Warn about parameter typestate mismatches upon return.
64 /// \param Loc -- The SourceLocation of the return statement.
66 /// \param ExpectedState -- The state the return value was expected to be
69 /// \param ObservedState -- The state the return value was observed to be
71 virtual void warnParamReturnTypestateMismatch(SourceLocation Loc,
72 StringRef VariableName,
73 StringRef ExpectedState,
74 StringRef ObservedState) {};
76 // FIXME: Add documentation.
77 virtual void warnParamTypestateMismatch(SourceLocation LOC,
78 StringRef ExpectedState,
79 StringRef ObservedState) {}
81 // FIXME: This can be removed when the attr propagation fix for templated
83 /// \brief Warn about return typestates set for unconsumable types.
85 /// \param Loc -- The location of the attributes.
87 /// \param TypeName -- The name of the unconsumable type.
88 virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
89 StringRef TypeName) {}
91 /// \brief Warn about return typestate mismatches.
93 /// \param Loc -- The SourceLocation of the return statement.
95 /// \param ExpectedState -- The state the return value was expected to be
98 /// \param ObservedState -- The state the return value was observed to be
100 virtual void warnReturnTypestateMismatch(SourceLocation Loc,
101 StringRef ExpectedState,
102 StringRef ObservedState) {}
104 /// \brief Warn about use-while-consumed errors.
105 /// \param MethodName -- The name of the method that was incorrectly
108 /// \param State -- The state the object was used in.
110 /// \param Loc -- The SourceLocation of the method invocation.
111 virtual void warnUseOfTempInInvalidState(StringRef MethodName,
113 SourceLocation Loc) {}
115 /// \brief Warn about use-while-consumed errors.
116 /// \param MethodName -- The name of the method that was incorrectly
119 /// \param State -- The state the object was used in.
121 /// \param VariableName -- The name of the variable that holds the unique
124 /// \param Loc -- The SourceLocation of the method invocation.
125 virtual void warnUseInInvalidState(StringRef MethodName,
126 StringRef VariableName,
128 SourceLocation Loc) {}
131 class ConsumedStateMap {
133 typedef llvm::DenseMap<const VarDecl *, ConsumedState> VarMapType;
134 typedef llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState>
145 ConsumedStateMap() : Reachable(true), From(NULL) {}
146 ConsumedStateMap(const ConsumedStateMap &Other)
147 : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
150 /// \brief Warn if any of the parameters being tracked are not in the state
151 /// they were declared to be in upon return from a function.
152 void checkParamsForReturnTypestate(SourceLocation BlameLoc,
153 ConsumedWarningsHandlerBase &WarningsHandler) const;
155 /// \brief Clear the TmpMap.
156 void clearTemporaries();
158 /// \brief Get the consumed state of a given variable.
159 ConsumedState getState(const VarDecl *Var) const;
161 /// \brief Get the consumed state of a given temporary value.
162 ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const;
164 /// \brief Merge this state map with another map.
165 void intersect(const ConsumedStateMap *Other);
167 void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack,
168 const ConsumedStateMap *LoopBackStates,
169 ConsumedWarningsHandlerBase &WarningsHandler);
171 /// \brief Return true if this block is reachable.
172 bool isReachable() const { return Reachable; }
174 /// \brief Mark the block as unreachable.
175 void markUnreachable();
177 /// \brief Set the source for a decision about the branching of states.
178 /// \param Source -- The statement that was the origin of a branching
180 void setSource(const Stmt *Source) { this->From = Source; }
182 /// \brief Set the consumed state of a given variable.
183 void setState(const VarDecl *Var, ConsumedState State);
185 /// \brief Set the consumed state of a given temporary value.
186 void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State);
188 /// \brief Remove the variable from our state map.
189 void remove(const VarDecl *Var);
191 /// \brief Tests to see if there is a mismatch in the states stored in two
194 /// \param Other -- The second map to compare against.
195 bool operator!=(const ConsumedStateMap *Other) const;
198 class ConsumedBlockInfo {
199 std::vector<ConsumedStateMap*> StateMapsArray;
200 std::vector<unsigned int> VisitOrder;
203 ConsumedBlockInfo() { }
205 ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
206 : StateMapsArray(NumBlocks, 0), VisitOrder(NumBlocks, 0) {
207 unsigned int VisitOrderCounter = 0;
208 for (PostOrderCFGView::iterator BI = SortedGraph->begin(),
209 BE = SortedGraph->end(); BI != BE; ++BI) {
210 VisitOrder[(*BI)->getBlockID()] = VisitOrderCounter++;
214 bool allBackEdgesVisited(const CFGBlock *CurrBlock,
215 const CFGBlock *TargetBlock);
217 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap,
219 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap);
221 ConsumedStateMap* borrowInfo(const CFGBlock *Block);
223 void discardInfo(const CFGBlock *Block);
225 ConsumedStateMap* getInfo(const CFGBlock *Block);
227 bool isBackEdge(const CFGBlock *From, const CFGBlock *To);
228 bool isBackEdgeTarget(const CFGBlock *Block);
231 /// A class that handles the analysis of uniqueness violations.
232 class ConsumedAnalyzer {
234 ConsumedBlockInfo BlockInfo;
235 ConsumedStateMap *CurrStates;
237 ConsumedState ExpectedReturnState;
239 void determineExpectedReturnState(AnalysisDeclContext &AC,
240 const FunctionDecl *D);
241 bool hasConsumableAttributes(const CXXRecordDecl *RD);
242 bool splitState(const CFGBlock *CurrBlock,
243 const ConsumedStmtVisitor &Visitor);
247 ConsumedWarningsHandlerBase &WarningsHandler;
249 ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
250 : WarningsHandler(WarningsHandler) {}
252 ConsumedState getExpectedReturnState() const { return ExpectedReturnState; }
254 /// \brief Check a function's CFG for consumed violations.
256 /// We traverse the blocks in the CFG, keeping track of the state of each
257 /// value who's type has uniquness annotations. If methods are invoked in
258 /// the wrong state a warning is issued. Each block in the CFG is traversed
260 void run(AnalysisDeclContext &AC);
262 }} // end namespace clang::consumed