Consumed.h revision 5fdd207ec8f4c1f58bd74f8a84ce1935487563ce
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 typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes; 29 typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag; 30 typedef std::list<DelayedDiag> DiagList; 31 32 class ConsumedWarningsHandlerBase { 33 34 public: 35 36 virtual ~ConsumedWarningsHandlerBase(); 37 38 /// \brief Emit the warnings and notes left by the analysis. 39 virtual void emitDiagnostics() {} 40 41 /// Warn about unnecessary-test errors. 42 /// \param VariableName -- The name of the variable that holds the unique 43 /// value. 44 /// 45 /// \param Loc -- The SourceLocation of the unnecessary test. 46 virtual void warnUnnecessaryTest(StringRef VariableName, 47 StringRef VariableState, 48 SourceLocation Loc) {} 49 50 /// Warn about use-while-consumed errors. 51 /// \param MethodName -- The name of the method that was incorrectly 52 /// invoked. 53 /// 54 /// \param Loc -- The SourceLocation of the method invocation. 55 virtual void warnUseOfTempWhileConsumed(StringRef MethodName, 56 SourceLocation Loc) {} 57 58 /// Warn about use-in-unknown-state errors. 59 /// \param MethodName -- The name of the method that was incorrectly 60 /// invoked. 61 /// 62 /// \param Loc -- The SourceLocation of the method invocation. 63 virtual void warnUseOfTempInUnknownState(StringRef MethodName, 64 SourceLocation Loc) {} 65 66 /// Warn about use-while-consumed errors. 67 /// \param MethodName -- The name of the method that was incorrectly 68 /// invoked. 69 /// 70 /// \param VariableName -- The name of the variable that holds the unique 71 /// value. 72 /// 73 /// \param Loc -- The SourceLocation of the method invocation. 74 virtual void warnUseWhileConsumed(StringRef MethodName, 75 StringRef VariableName, 76 SourceLocation Loc) {} 77 78 /// Warn about use-in-unknown-state errors. 79 /// \param MethodName -- The name of the method that was incorrectly 80 /// invoked. 81 /// 82 /// \param VariableName -- The name of the variable that holds the unique 83 /// value. 84 /// 85 /// \param Loc -- The SourceLocation of the method invocation. 86 virtual void warnUseInUnknownState(StringRef MethodName, 87 StringRef VariableName, 88 SourceLocation Loc) {} 89 }; 90 91 enum ConsumedState { 92 // No state information for the given variable. 93 CS_None, 94 95 CS_Unknown, 96 CS_Unconsumed, 97 CS_Consumed 98 }; 99 100 class ConsumedStateMap { 101 102 typedef llvm::DenseMap<const VarDecl *, ConsumedState> MapType; 103 typedef std::pair<const VarDecl *, ConsumedState> PairType; 104 105 protected: 106 107 MapType Map; 108 109 public: 110 /// \brief Get the consumed state of a given variable. 111 ConsumedState getState(const VarDecl *Var); 112 113 /// \brief Merge this state map with another map. 114 void intersect(const ConsumedStateMap *Other); 115 116 /// \brief Mark all variables as unknown. 117 void makeUnknown(); 118 119 /// \brief Set the consumed state of a given variable. 120 void setState(const VarDecl *Var, ConsumedState State); 121 122 /// \brief Remove the variable from our state map. 123 void remove(const VarDecl *Var); 124 }; 125 126 class ConsumedBlockInfo { 127 128 ConsumedStateMap **StateMapsArray; 129 PostOrderCFGView::CFGBlockSet VisitedBlocks; 130 131 public: 132 133 ConsumedBlockInfo() : StateMapsArray(NULL) {} 134 135 ConsumedBlockInfo(const CFG *CFGraph) 136 : StateMapsArray(new ConsumedStateMap*[CFGraph->getNumBlockIDs()]()), 137 VisitedBlocks(CFGraph) {} 138 139 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, 140 bool &AlreadyOwned); 141 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap); 142 143 ConsumedStateMap* getInfo(const CFGBlock *Block); 144 145 void markVisited(const CFGBlock *Block); 146 }; 147 148 struct VarTestResult { 149 const VarDecl *Var; 150 SourceLocation Loc; 151 bool UnconsumedInTrueBranch; 152 153 VarTestResult() : Var(NULL), Loc(), UnconsumedInTrueBranch(true) {} 154 155 VarTestResult(const VarDecl *Var, SourceLocation Loc, 156 bool UnconsumedInTrueBranch) 157 : Var(Var), Loc(Loc), UnconsumedInTrueBranch(UnconsumedInTrueBranch) {} 158 }; 159 160 /// A class that handles the analysis of uniqueness violations. 161 class ConsumedAnalyzer { 162 163 typedef llvm::DenseMap<const CXXRecordDecl *, bool> CacheMapType; 164 typedef std::pair<const CXXRecordDecl *, bool> CachePairType; 165 166 ConsumedBlockInfo BlockInfo; 167 ConsumedStateMap *CurrStates; 168 169 CacheMapType ConsumableTypeCache; 170 171 bool hasConsumableAttributes(const CXXRecordDecl *RD); 172 void splitState(const CFGBlock *CurrBlock, const IfStmt *Terminator); 173 174 public: 175 176 ConsumedWarningsHandlerBase &WarningsHandler; 177 178 ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler) 179 : WarningsHandler(WarningsHandler) {} 180 181 /// \brief Check to see if the type is a consumable type. 182 bool isConsumableType(QualType Type); 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