clang API Documentation
00001 //== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines CheckerContext that provides contextual info for 00011 // path-sensitive checkers. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H 00016 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H 00017 00018 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 00019 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 00020 00021 namespace clang { 00022 namespace ento { 00023 00024 /// Declares an immutable map of type \p NameTy, suitable for placement into 00025 /// the ProgramState. This is implementing using llvm::ImmutableMap. 00026 /// 00027 /// \code 00028 /// State = State->set<Name>(K, V); 00029 /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map. 00030 /// State = State->remove<Name>(K); 00031 /// NameTy Map = State->get<Name>(); 00032 /// \endcode 00033 /// 00034 /// The macro should not be used inside namespaces, or for traits that must 00035 /// be accessible from more than one translation unit. 00036 #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \ 00037 REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \ 00038 CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value)) 00039 00040 /// Declares an immutable set of type \p NameTy, suitable for placement into 00041 /// the ProgramState. This is implementing using llvm::ImmutableSet. 00042 /// 00043 /// \code 00044 /// State = State->add<Name>(E); 00045 /// State = State->remove<Name>(E); 00046 /// bool Present = State->contains<Name>(E); 00047 /// NameTy Set = State->get<Name>(); 00048 /// \endcode 00049 /// 00050 /// The macro should not be used inside namespaces, or for traits that must 00051 /// be accessible from more than one translation unit. 00052 #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \ 00053 REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>) 00054 00055 /// Declares an immutable list of type \p NameTy, suitable for placement into 00056 /// the ProgramState. This is implementing using llvm::ImmutableList. 00057 /// 00058 /// \code 00059 /// State = State->add<Name>(E); // Adds to the /end/ of the list. 00060 /// bool Present = State->contains<Name>(E); 00061 /// NameTy List = State->get<Name>(); 00062 /// \endcode 00063 /// 00064 /// The macro should not be used inside namespaces, or for traits that must 00065 /// be accessible from more than one translation unit. 00066 #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \ 00067 REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>) 00068 00069 00070 class CheckerContext { 00071 ExprEngine &Eng; 00072 /// The current exploded(symbolic execution) graph node. 00073 ExplodedNode *Pred; 00074 /// The flag is true if the (state of the execution) has been modified 00075 /// by the checker using this context. For example, a new transition has been 00076 /// added or a bug report issued. 00077 bool Changed; 00078 /// The tagged location, which is used to generate all new nodes. 00079 const ProgramPoint Location; 00080 NodeBuilder &NB; 00081 00082 public: 00083 /// If we are post visiting a call, this flag will be set if the 00084 /// call was inlined. In all other cases it will be false. 00085 const bool wasInlined; 00086 00087 CheckerContext(NodeBuilder &builder, 00088 ExprEngine &eng, 00089 ExplodedNode *pred, 00090 const ProgramPoint &loc, 00091 bool wasInlined = false) 00092 : Eng(eng), 00093 Pred(pred), 00094 Changed(false), 00095 Location(loc), 00096 NB(builder), 00097 wasInlined(wasInlined) { 00098 assert(Pred->getState() && 00099 "We should not call the checkers on an empty state."); 00100 } 00101 00102 AnalysisManager &getAnalysisManager() { 00103 return Eng.getAnalysisManager(); 00104 } 00105 00106 ConstraintManager &getConstraintManager() { 00107 return Eng.getConstraintManager(); 00108 } 00109 00110 StoreManager &getStoreManager() { 00111 return Eng.getStoreManager(); 00112 } 00113 00114 /// \brief Returns the previous node in the exploded graph, which includes 00115 /// the state of the program before the checker ran. Note, checkers should 00116 /// not retain the node in their state since the nodes might get invalidated. 00117 ExplodedNode *getPredecessor() { return Pred; } 00118 const ProgramStateRef &getState() const { return Pred->getState(); } 00119 00120 /// \brief Check if the checker changed the state of the execution; ex: added 00121 /// a new transition or a bug report. 00122 bool isDifferent() { return Changed; } 00123 00124 /// \brief Returns the number of times the current block has been visited 00125 /// along the analyzed path. 00126 unsigned blockCount() const { 00127 return NB.getContext().blockCount(); 00128 } 00129 00130 ASTContext &getASTContext() { 00131 return Eng.getContext(); 00132 } 00133 00134 const LangOptions &getLangOpts() const { 00135 return Eng.getContext().getLangOpts(); 00136 } 00137 00138 const LocationContext *getLocationContext() const { 00139 return Pred->getLocationContext(); 00140 } 00141 00142 const StackFrameContext *getStackFrame() const { 00143 return Pred->getStackFrame(); 00144 } 00145 00146 /// Return true if the current LocationContext has no caller context. 00147 bool inTopFrame() const { return getLocationContext()->inTopFrame(); } 00148 00149 BugReporter &getBugReporter() { 00150 return Eng.getBugReporter(); 00151 } 00152 00153 SourceManager &getSourceManager() { 00154 return getBugReporter().getSourceManager(); 00155 } 00156 00157 SValBuilder &getSValBuilder() { 00158 return Eng.getSValBuilder(); 00159 } 00160 00161 SymbolManager &getSymbolManager() { 00162 return getSValBuilder().getSymbolManager(); 00163 } 00164 00165 bool isObjCGCEnabled() const { 00166 return Eng.isObjCGCEnabled(); 00167 } 00168 00169 ProgramStateManager &getStateManager() { 00170 return Eng.getStateManager(); 00171 } 00172 00173 AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 00174 return Pred->getLocationContext()->getAnalysisDeclContext(); 00175 } 00176 00177 /// \brief Get the blockID. 00178 unsigned getBlockID() const { 00179 return NB.getContext().getBlock()->getBlockID(); 00180 } 00181 00182 /// \brief If the given node corresponds to a PostStore program point, 00183 /// retrieve the location region as it was uttered in the code. 00184 /// 00185 /// This utility can be useful for generating extensive diagnostics, for 00186 /// example, for finding variables that the given symbol was assigned to. 00187 static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) { 00188 ProgramPoint L = N->getLocation(); 00189 if (Optional<PostStore> PSL = L.getAs<PostStore>()) 00190 return reinterpret_cast<const MemRegion*>(PSL->getLocationValue()); 00191 return nullptr; 00192 } 00193 00194 /// \brief Get the value of arbitrary expressions at this point in the path. 00195 SVal getSVal(const Stmt *S) const { 00196 return getState()->getSVal(S, getLocationContext()); 00197 } 00198 00199 /// \brief Generates a new transition in the program state graph 00200 /// (ExplodedGraph). Uses the default CheckerContext predecessor node. 00201 /// 00202 /// @param State The state of the generated node. If not specified, the state 00203 /// will not be changed, but the new node will have the checker's tag. 00204 /// @param Tag The tag is used to uniquely identify the creation site. If no 00205 /// tag is specified, a default tag, unique to the given checker, 00206 /// will be used. Tags are used to prevent states generated at 00207 /// different sites from caching out. 00208 ExplodedNode *addTransition(ProgramStateRef State = nullptr, 00209 const ProgramPointTag *Tag = nullptr) { 00210 return addTransitionImpl(State ? State : getState(), false, nullptr, Tag); 00211 } 00212 00213 /// \brief Generates a new transition with the given predecessor. 00214 /// Allows checkers to generate a chain of nodes. 00215 /// 00216 /// @param State The state of the generated node. 00217 /// @param Pred The transition will be generated from the specified Pred node 00218 /// to the newly generated node. 00219 /// @param Tag The tag to uniquely identify the creation site. 00220 ExplodedNode *addTransition(ProgramStateRef State, 00221 ExplodedNode *Pred, 00222 const ProgramPointTag *Tag = nullptr) { 00223 return addTransitionImpl(State, false, Pred, Tag); 00224 } 00225 00226 /// \brief Generate a sink node. Generating a sink stops exploration of the 00227 /// given path. 00228 ExplodedNode *generateSink(ProgramStateRef State = nullptr, 00229 ExplodedNode *Pred = nullptr, 00230 const ProgramPointTag *Tag = nullptr) { 00231 return addTransitionImpl(State ? State : getState(), true, Pred, Tag); 00232 } 00233 00234 /// \brief Emit the diagnostics report. 00235 void emitReport(BugReport *R) { 00236 Changed = true; 00237 Eng.getBugReporter().emitReport(R); 00238 } 00239 00240 /// \brief Get the declaration of the called function (path-sensitive). 00241 const FunctionDecl *getCalleeDecl(const CallExpr *CE) const; 00242 00243 /// \brief Get the name of the called function (path-sensitive). 00244 StringRef getCalleeName(const FunctionDecl *FunDecl) const; 00245 00246 /// \brief Get the identifier of the called function (path-sensitive). 00247 const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const { 00248 const FunctionDecl *FunDecl = getCalleeDecl(CE); 00249 if (FunDecl) 00250 return FunDecl->getIdentifier(); 00251 else 00252 return nullptr; 00253 } 00254 00255 /// \brief Get the name of the called function (path-sensitive). 00256 StringRef getCalleeName(const CallExpr *CE) const { 00257 const FunctionDecl *FunDecl = getCalleeDecl(CE); 00258 return getCalleeName(FunDecl); 00259 } 00260 00261 /// \brief Returns true if the callee is an externally-visible function in the 00262 /// top-level namespace, such as \c malloc. 00263 /// 00264 /// If a name is provided, the function must additionally match the given 00265 /// name. 00266 /// 00267 /// Note that this deliberately excludes C++ library functions in the \c std 00268 /// namespace, but will include C library functions accessed through the 00269 /// \c std namespace. This also does not check if the function is declared 00270 /// as 'extern "C"', or if it uses C++ name mangling. 00271 static bool isCLibraryFunction(const FunctionDecl *FD, 00272 StringRef Name = StringRef()); 00273 00274 /// \brief Depending on wither the location corresponds to a macro, return 00275 /// either the macro name or the token spelling. 00276 /// 00277 /// This could be useful when checkers' logic depends on whether a function 00278 /// is called with a given macro argument. For example: 00279 /// s = socket(AF_INET,..) 00280 /// If AF_INET is a macro, the result should be treated as a source of taint. 00281 /// 00282 /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName(). 00283 StringRef getMacroNameOrSpelling(SourceLocation &Loc); 00284 00285 private: 00286 ExplodedNode *addTransitionImpl(ProgramStateRef State, 00287 bool MarkAsSink, 00288 ExplodedNode *P = nullptr, 00289 const ProgramPointTag *Tag = nullptr) { 00290 if (!State || (State == Pred->getState() && !Tag && !MarkAsSink)) 00291 return Pred; 00292 00293 Changed = true; 00294 const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location); 00295 if (!P) 00296 P = Pred; 00297 00298 ExplodedNode *node; 00299 if (MarkAsSink) 00300 node = NB.generateSink(LocalLoc, State, P); 00301 else 00302 node = NB.generateNode(LocalLoc, State, P); 00303 return node; 00304 } 00305 }; 00306 00307 } // end GR namespace 00308 00309 } // end clang namespace 00310 00311 #endif