Consumed.h revision b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3
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 typedef llvm::DenseMap<const CXXRecordDecl *, bool> CacheMapType; 171 typedef std::pair<const CXXRecordDecl *, bool> CachePairType; 172 173 ConsumedBlockInfo BlockInfo; 174 ConsumedStateMap *CurrStates; 175 176 CacheMapType ConsumableTypeCache; 177 178 bool hasConsumableAttributes(const CXXRecordDecl *RD); 179 bool splitState(const CFGBlock *CurrBlock, 180 const ConsumedStmtVisitor &Visitor); 181 182 public: 183 184 ConsumedWarningsHandlerBase &WarningsHandler; 185 186 ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler) 187 : WarningsHandler(WarningsHandler) {} 188 189 /// \brief Check to see if the type is a consumable type. 190 bool isConsumableType(QualType Type); 191 192 /// \brief Check a function's CFG for consumed violations. 193 /// 194 /// We traverse the blocks in the CFG, keeping track of the state of each 195 /// value who's type has uniquness annotations. If methods are invoked in 196 /// the wrong state a warning is issued. Each block in the CFG is traversed 197 /// exactly once. 198 void run(AnalysisDeclContext &AC); 199 }; 200}} // end namespace clang::consumed 201 202#endif 203