CheckerContext.h revision 57300760964904cc022a175643342f29f46b7e6b
111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=// 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The LLVM Compiler Infrastructure 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is distributed under the University of Illinois Open Source 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// License. See LICENSE.TXT for details. 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file defines CheckerContext that provides contextual info for 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// path-sensitive checkers. 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace clang { 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace ento { 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass CheckerContext { 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExprEngine &Eng; 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// The current exploded(symbolic execution) graph node. 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *Pred; 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// The flag is true if the (state of the execution) has been modified 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// by the checker using this context. For example, a new transition has been 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// added or a bug report issued. 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool Changed; 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// The tagged location, which is used to generate all new nodes. 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const ProgramPoint Location; 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert NodeBuilder &NB; 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic: 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert CheckerContext(NodeBuilder &builder, 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExprEngine &eng, 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *pred, 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const ProgramPoint &loc) 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : Eng(eng), 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Pred(pred), 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Changed(false), 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Location(loc), 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert NB(builder) { 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(Pred->getState() && 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "We should not call the checkers on an empty state."); 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert AnalysisManager &getAnalysisManager() { 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getAnalysisManager(); 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ConstraintManager &getConstraintManager() { 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getConstraintManager(); 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert StoreManager &getStoreManager() { 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getStoreManager(); 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Returns the previous node in the exploded graph, which includes 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// the state of the program before the checker ran. Note, checkers should 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// not retain the node in their state since the nodes might get invalidated. 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *getPredecessor() { return Pred; } 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ProgramStateRef getState() const { return Pred->getState(); } 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Check if the checker changed the state of the execution; ex: added 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// a new transition or a bug report. 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool isDifferent() { return Changed; } 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Returns the number of times the current block has been visited 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// along the analyzed path. 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unsigned getCurrentBlockCount() const { 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return NB.getContext().getCurrentBlockCount(); 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ASTContext &getASTContext() { 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getContext(); 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const LangOptions &getLangOptions() const { 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getContext().getLangOptions(); 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const LocationContext *getLocationContext() const { 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Pred->getLocationContext(); 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert BugReporter &getBugReporter() { 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getBugReporter(); 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SourceManager &getSourceManager() { 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return getBugReporter().getSourceManager(); 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SValBuilder &getSValBuilder() { 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getSValBuilder(); 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SymbolManager &getSymbolManager() { 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return getSValBuilder().getSymbolManager(); 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool isObjCGCEnabled() const { 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.isObjCGCEnabled(); 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ProgramStateManager &getStateManager() { 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Eng.getStateManager(); 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return Pred->getLocationContext()->getAnalysisDeclContext(); 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Generates a new transition in the program state graph 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// (ExplodedGraph). Uses the default CheckerContext predecessor node. 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// @param State The state of the generated node. 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// @param Tag The tag is used to uniquely identify the creation site. If no 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// tag is specified, a default tag, unique to the given checker, 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// will be used. Tags are used to prevent states generated at 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// different sites from caching out. 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *addTransition(ProgramStateRef State, 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const ProgramPointTag *Tag = 0) { 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return addTransitionImpl(State, false, 0, Tag); 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Generates a default transition (containing checker tag but no 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// checker state changes). 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *addTransition() { 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return addTransition(getState()); 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Generates a new transition with the given predecessor. 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// Allows checkers to generate a chain of nodes. 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// @param State The state of the generated node. 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// @param Pred The transition will be generated from the specified Pred node 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// to the newly generated node. 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// @param Tag The tag to uniquely identify the creation site. 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// @param IsSink Mark the new node as sink, which will stop exploration of 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// the given path. 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *addTransition(ProgramStateRef State, 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *Pred, 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const ProgramPointTag *Tag = 0, 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool IsSink = false) { 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return addTransitionImpl(State, IsSink, Pred, Tag); 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Generate a sink node. Generating sink stops exploration of the 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// given path. 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *generateSink(ProgramStateRef state = 0) { 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return addTransitionImpl(state ? state : getState(), true); 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Emit the diagnostics report. 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void EmitReport(BugReport *R) { 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Changed = true; 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Eng.getBugReporter().EmitReport(R); 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Get the declaration of the called function (path-sensitive). 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const FunctionDecl *getCalleeDecl(const CallExpr *CE) const; 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Get the name of the called function (path-sensitive). 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert StringRef getCalleeName(const FunctionDecl *FunDecl) const; 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Get the name of the called function (path-sensitive). 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert StringRef getCalleeName(const CallExpr *CE) const { 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const FunctionDecl *FunDecl = getCalleeDecl(CE); 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return getCalleeName(FunDecl); 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// Given a function declaration and a name checks if this is a C lib 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// function with the given name. 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name); 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name, 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ASTContext &Context); 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \brief Depending on wither the location corresponds to a macro, return 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// either the macro name or the token spelling. 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// This could be useful when checkers' logic depends on whether a function 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// is called with a given macro argument. For example: 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// s = socket(AF_INET,..) 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// If AF_INET is a macro, the result should be treated as a source of taint. 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName(). 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert StringRef getMacroNameOrSpelling(SourceLocation &Loc); 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertprivate: 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *addTransitionImpl(ProgramStateRef State, 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool MarkAsSink, 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ExplodedNode *P = 0, 197 const ProgramPointTag *Tag = 0) { 198 assert(State); 199 if (State == Pred->getState() && !Tag && !MarkAsSink) 200 return Pred; 201 202 Changed = true; 203 ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location, 204 State, 205 P ? P : Pred, MarkAsSink); 206 return node; 207 } 208}; 209 210/// \brief A helper class which wraps a boolean value set to false by default. 211struct DefaultBool { 212 bool Val; 213 DefaultBool() : Val(false) {} 214 operator bool() const { return Val; } 215 DefaultBool &operator=(bool b) { Val = b; return *this; } 216}; 217 218} // end GR namespace 219 220} // end clang namespace 221 222#endif 223