Consumed.h revision 039970aae2b7e59ac4de5f147dfbc3c91b275b9e
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 123 class ConsumedBlockInfo { 124 125 ConsumedStateMap **StateMapsArray; 126 PostOrderCFGView::CFGBlockSet VisitedBlocks; 127 128 public: 129 130 ConsumedBlockInfo() : StateMapsArray(NULL) {} 131 132 ConsumedBlockInfo(const CFG *CFGraph) 133 : StateMapsArray(new ConsumedStateMap*[CFGraph->getNumBlockIDs()]()), 134 VisitedBlocks(CFGraph) {} 135 136 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, 137 bool &AlreadyOwned); 138 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap); 139 140 ConsumedStateMap* getInfo(const CFGBlock *Block); 141 142 void markVisited(const CFGBlock *Block); 143 }; 144 145 struct VarTestResult { 146 const VarDecl *Var; 147 SourceLocation Loc; 148 bool UnconsumedInTrueBranch; 149 150 VarTestResult() : Var(NULL), Loc(), UnconsumedInTrueBranch(true) {} 151 152 VarTestResult(const VarDecl *Var, SourceLocation Loc, 153 bool UnconsumedInTrueBranch) 154 : Var(Var), Loc(Loc), UnconsumedInTrueBranch(UnconsumedInTrueBranch) {} 155 }; 156 157 /// A class that handles the analysis of uniqueness violations. 158 class ConsumedAnalyzer { 159 160 typedef llvm::DenseMap<const CXXRecordDecl *, bool> CacheMapType; 161 typedef std::pair<const CXXRecordDecl *, bool> CachePairType; 162 163 ConsumedBlockInfo BlockInfo; 164 ConsumedStateMap *CurrStates; 165 166 CacheMapType ConsumableTypeCache; 167 168 bool hasConsumableAttributes(const CXXRecordDecl *RD); 169 void splitState(const CFGBlock *CurrBlock, const IfStmt *Terminator); 170 171 public: 172 173 ConsumedWarningsHandlerBase &WarningsHandler; 174 175 ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler) 176 : WarningsHandler(WarningsHandler) {} 177 178 /// \brief Check to see if the type is a consumable type. 179 bool isConsumableType(QualType Type); 180 181 /// \brief Check a function's CFG for consumed violations. 182 /// 183 /// We traverse the blocks in the CFG, keeping track of the state of each 184 /// value who's type has uniquness annotations. If methods are invoked in 185 /// the wrong state a warning is issued. Each block in the CFG is traversed 186 /// exactly once. 187 void run(AnalysisDeclContext &AC); 188 }; 189 190 /// \brief Check to see if a function tests an object's validity. 191 bool isTestingFunction(const CXXMethodDecl *MethodDecl); 192 193}} // end namespace clang::consumed 194 195#endif 196