CheckerContext.h revision 9b0c749a20d0f7d0e63441d76baa15def3f37fdb
1//== CheckerContext.h - Context info for path-sensitive checkers--*- 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// This file defines CheckerContext that provides contextual info for 11// path-sensitive checkers. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 16#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 17 18#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 19 20namespace clang { 21namespace ento { 22 23class CheckerContext { 24 ExprEngine &Eng; 25 ExplodedNode *Pred; 26 const ProgramPoint Location; 27 NodeBuilder &NB; 28 29public: 30 CheckerContext(NodeBuilder &builder, 31 ExprEngine &eng, 32 ExplodedNode *pred, 33 const ProgramPoint &loc) 34 : Eng(eng), 35 Pred(pred), 36 Location(loc), 37 NB(builder) { 38 assert(Pred->getState() && 39 "We should not call the checkers on an empty state."); 40 } 41 42 AnalysisManager &getAnalysisManager() { 43 return Eng.getAnalysisManager(); 44 } 45 46 ConstraintManager &getConstraintManager() { 47 return Eng.getConstraintManager(); 48 } 49 50 StoreManager &getStoreManager() { 51 return Eng.getStoreManager(); 52 } 53 54 /// \brief Returns the previous node in the exploded graph, which includes 55 /// the state of the program before the checker ran. Note, checkers should 56 /// not retain the node in their state since the nodes might get invalidated. 57 ExplodedNode *getPredecessor() { return Pred; } 58 const ProgramState *getState() const { return Pred->getState(); } 59 60 /// \brief Returns the number of times the current block has been visited 61 /// along the analyzed path. 62 unsigned getCurrentBlockCount() const { 63 return NB.getContext().getCurrentBlockCount(); 64 } 65 66 ASTContext &getASTContext() { 67 return Eng.getContext(); 68 } 69 70 const LocationContext *getLocationContext() const { 71 return Pred->getLocationContext(); 72 } 73 74 BugReporter &getBugReporter() { 75 return Eng.getBugReporter(); 76 } 77 78 SourceManager &getSourceManager() { 79 return getBugReporter().getSourceManager(); 80 } 81 82 SValBuilder &getSValBuilder() { 83 return Eng.getSValBuilder(); 84 } 85 86 SymbolManager &getSymbolManager() { 87 return getSValBuilder().getSymbolManager(); 88 } 89 90 bool isObjCGCEnabled() const { 91 return Eng.isObjCGCEnabled(); 92 } 93 94 ProgramStateManager &getStateManager() { 95 return Eng.getStateManager(); 96 } 97 98 AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 99 return Pred->getLocationContext()->getAnalysisDeclContext(); 100 } 101 102 /// \brief Generates a new transition in the program state graph 103 /// (ExplodedGraph). Uses the default CheckerContext predecessor node. 104 /// 105 /// @param State The state of the generated node. 106 /// @param Tag The tag is used to uniquely identify the creation site. If no 107 /// tag is specified, a default tag, unique to the given checker, 108 /// will be used. Tags are used to prevent states generated at 109 /// different sites from caching out. 110 ExplodedNode *addTransition(const ProgramState *State, 111 const ProgramPointTag *Tag = 0) { 112 return addTransitionImpl(State, false, 0, Tag); 113 } 114 115 /// \brief Generates a default transition (containing checker tag but no 116 /// checker state changes). 117 ExplodedNode *addTransition() { 118 return addTransition(getState()); 119 } 120 121 /// \brief Generates a new transition with the given predecessor. 122 /// Allows checkers to generate a chain of nodes. 123 /// 124 /// @param State The state of the generated node. 125 /// @param Pred The transition will be generated from the specified Pred node 126 /// to the newly generated node. 127 /// @param Tag The tag to uniquely identify the creation site. 128 /// @param IsSink Mark the new node as sink, which will stop exploration of 129 /// the given path. 130 ExplodedNode *addTransition(const ProgramState *State, 131 ExplodedNode *Pred, 132 const ProgramPointTag *Tag = 0, 133 bool IsSink = false) { 134 return addTransitionImpl(State, IsSink, Pred, Tag); 135 } 136 137 /// \brief Generate a sink node. Generating sink stops exploration of the 138 /// given path. 139 ExplodedNode *generateSink(const ProgramState *state = 0) { 140 return addTransitionImpl(state ? state : getState(), true); 141 } 142 143 /// \brief Emit the diagnostics report. 144 void EmitReport(BugReport *R) { 145 Eng.getBugReporter().EmitReport(R); 146 } 147 148 /// \brief Get the declaration of the called function (path-sensitive). 149 const FunctionDecl *getCalleeDecl(const CallExpr *CE) const; 150 151 /// \brief Get the name of the called function (path-sensitive). 152 StringRef getCalleeName(const FunctionDecl *FunDecl) const; 153 154 /// \brief Get the name of the called function (path-sensitive). 155 StringRef getCalleeName(const CallExpr *CE) const { 156 const FunctionDecl *FunDecl = getCalleeDecl(CE); 157 return getCalleeName(FunDecl); 158 } 159 160 /// Given a function declaration and a name checks if this is a C lib 161 /// function with the given name. 162 bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name); 163 164private: 165 ExplodedNode *addTransitionImpl(const ProgramState *State, 166 bool MarkAsSink, 167 ExplodedNode *P = 0, 168 const ProgramPointTag *Tag = 0) { 169 assert(State); 170 if (State == Pred->getState() && !Tag && !MarkAsSink) 171 return Pred; 172 173 ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location, 174 State, 175 P ? P : Pred, MarkAsSink); 176 return node; 177 } 178}; 179 180} // end GR namespace 181 182} // end clang namespace 183 184#endif 185