CheckerContext.h revision eeea7c44a6986752fedee1ef1bcef855db373872
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 39 AnalysisManager &getAnalysisManager() { 40 return Eng.getAnalysisManager(); 41 } 42 43 ConstraintManager &getConstraintManager() { 44 return Eng.getConstraintManager(); 45 } 46 47 StoreManager &getStoreManager() { 48 return Eng.getStoreManager(); 49 } 50 51 /// \brief Returns the previous node in the exploded graph, which includes 52 /// the state of the program before the checker ran. Note, checkers should 53 /// not retain the node in their state since the nodes might get invalidated. 54 ExplodedNode *getPredecessor() { return Pred; } 55 const ProgramState *getState() const { return Pred->getState(); } 56 57 /// \brief Returns the number of times the current block has been visited 58 /// along the analyzed path. 59 unsigned getCurrentBlockCount() const { 60 return NB.getContext().getCurrentBlockCount(); 61 } 62 63 ASTContext &getASTContext() { 64 return Eng.getContext(); 65 } 66 67 const LocationContext *getLocationContext() const { 68 return Pred->getLocationContext(); 69 } 70 71 BugReporter &getBugReporter() { 72 return Eng.getBugReporter(); 73 } 74 75 SourceManager &getSourceManager() { 76 return getBugReporter().getSourceManager(); 77 } 78 79 SValBuilder &getSValBuilder() { 80 return Eng.getSValBuilder(); 81 } 82 83 SymbolManager &getSymbolManager() { 84 return getSValBuilder().getSymbolManager(); 85 } 86 87 bool isObjCGCEnabled() const { 88 return Eng.isObjCGCEnabled(); 89 } 90 91 ProgramStateManager &getStateManager() { 92 return Eng.getStateManager(); 93 } 94 95 AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 96 return Pred->getLocationContext()->getAnalysisDeclContext(); 97 } 98 99 /// \brief Generates a new transition in the program state graph 100 /// (ExplodedGraph). Uses the default CheckerContext predecessor node. 101 /// 102 /// @param State The state of the generated node. 103 /// @param Tag The tag is used to uniquely identify the creation site. If no 104 /// tag is specified, a default tag, unique to the given checker, 105 /// will be used. Tags are used to prevent states generated at 106 /// different sites from caching out. 107 ExplodedNode *addTransition(const ProgramState *State, 108 const ProgramPointTag *Tag = 0) { 109 return addTransitionImpl(State, false, 0, Tag); 110 } 111 112 /// \brief Generates a default transition (containing checker tag but no 113 /// checker state changes). 114 ExplodedNode *addTransition() { 115 return addTransition(getState()); 116 } 117 118 /// \brief Generates a new transition with the given predecessor. 119 /// Allows checkers to generate a chain of nodes. 120 /// 121 /// @param State The state of the generated node. 122 /// @param Pred The transition will be generated from the specified Pred node 123 /// to the newly generated node. 124 /// @param Tag The tag to uniquely identify the creation site. 125 /// @param IsSink Mark the new node as sink, which will stop exploration of 126 /// the given path. 127 ExplodedNode *addTransition(const ProgramState *State, 128 ExplodedNode *Pred, 129 const ProgramPointTag *Tag = 0, 130 bool IsSink = false) { 131 return addTransitionImpl(State, IsSink, Pred, Tag); 132 } 133 134 /// \brief Generate a sink node. Generating sink stops exploration of the 135 /// given path. 136 ExplodedNode *generateSink(const ProgramState *state = 0) { 137 return addTransitionImpl(state ? state : getState(), true); 138 } 139 140 /// \brief Emit the diagnostics report. 141 void EmitReport(BugReport *R) { 142 Eng.getBugReporter().EmitReport(R); 143 } 144 145 /// \brief Get the name of the called function (path-sensitive). 146 StringRef getCalleeName(const CallExpr *CE) const; 147 148private: 149 ExplodedNode *addTransitionImpl(const ProgramState *State, 150 bool MarkAsSink, 151 ExplodedNode *P = 0, 152 const ProgramPointTag *Tag = 0) { 153 assert(State); 154 if (State == Pred->getState() && !Tag && !MarkAsSink) 155 return Pred; 156 157 ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location, 158 State, 159 P ? P : Pred, MarkAsSink); 160 return node; 161 } 162}; 163 164} // end GR namespace 165 166} // end clang namespace 167 168#endif 169