16bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=// 26bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 36bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 46bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 56bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 66bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 76bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 86bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 96bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 106bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// This file defines CheckerContext that provides contextual info for 116bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// path-sensitive checkers. 126bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 136bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 146bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 156bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 166bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 176bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 186bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 1940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 205ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks 216bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace clang { 226bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace ento { 236bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 2440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// Declares an immutable map of type \p NameTy, suitable for placement into 25964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// the ProgramState. This is implementing using llvm::ImmutableMap. 26964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// 27964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// \code 28964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// State = State->set<Name>(K, V); 29964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map. 30964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// State = State->remove<Name>(K); 31964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// NameTy Map = State->get<Name>(); 32964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// \endcode 3340d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// 3440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// The macro should not be used inside namespaces, or for traits that must 3540d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// be accessible from more than one translation unit. 3640d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \ 3740d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \ 3840d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value)) 3940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose 40964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// Declares an immutable set of type \p NameTy, suitable for placement into 41964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// the ProgramState. This is implementing using llvm::ImmutableSet. 42964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// 43964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// \code 44964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// State = State->add<Name>(E); 45964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// State = State->remove<Name>(E); 46964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// bool Present = State->contains<Name>(E); 47964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// NameTy Set = State->get<Name>(); 48964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// \endcode 4940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// 5040d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// The macro should not be used inside namespaces, or for traits that must 5140d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// be accessible from more than one translation unit. 5240d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \ 5340d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>) 5440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose 5540d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// Declares an immutable list of type \p NameTy, suitable for placement into 56964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// the ProgramState. This is implementing using llvm::ImmutableList. 57964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// 58964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// \code 59964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// State = State->add<Name>(E); // Adds to the /end/ of the list. 60964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// bool Present = State->contains<Name>(E); 61964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// NameTy List = State->get<Name>(); 62964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose /// \endcode 6340d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// 6440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// The macro should not be used inside namespaces, or for traits that must 6540d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose /// be accessible from more than one translation unit. 6640d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \ 6740d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>) 6840d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose 6940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose 706bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisclass CheckerContext { 716bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExprEngine &Eng; 7257300760964904cc022a175643342f29f46b7e6bAnna Zaks /// The current exploded(symbolic execution) graph node. 736bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExplodedNode *Pred; 7457300760964904cc022a175643342f29f46b7e6bAnna Zaks /// The flag is true if the (state of the execution) has been modified 7557300760964904cc022a175643342f29f46b7e6bAnna Zaks /// by the checker using this context. For example, a new transition has been 7657300760964904cc022a175643342f29f46b7e6bAnna Zaks /// added or a bug report issued. 7757300760964904cc022a175643342f29f46b7e6bAnna Zaks bool Changed; 7857300760964904cc022a175643342f29f46b7e6bAnna Zaks /// The tagged location, which is used to generate all new nodes. 793f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint Location; 803152b3cb5b6a2f797d0972c81a5eb3fd69c0d620Anna Zaks NodeBuilder &NB; 81063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks 826bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidispublic: 83514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek /// If we are post visiting a call, this flag will be set if the 84514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek /// call was inlined. In all other cases it will be false. 85514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek const bool wasInlined; 86514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek 878ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks CheckerContext(NodeBuilder &builder, 8818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExprEngine &eng, 8918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExplodedNode *pred, 90514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek const ProgramPoint &loc, 91514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek bool wasInlined = false) 928ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks : Eng(eng), 9318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek Pred(pred), 9457300760964904cc022a175643342f29f46b7e6bAnna Zaks Changed(false), 953f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks Location(loc), 96514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek NB(builder), 97514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek wasInlined(wasInlined) { 98777d706547ebc751d998134774d9d5388fff8e02Anna Zaks assert(Pred->getState() && 99777d706547ebc751d998134774d9d5388fff8e02Anna Zaks "We should not call the checkers on an empty state."); 100777d706547ebc751d998134774d9d5388fff8e02Anna Zaks } 1016bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1026bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis AnalysisManager &getAnalysisManager() { 1036bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getAnalysisManager(); 1046bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1056bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1066bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ConstraintManager &getConstraintManager() { 1076bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getConstraintManager(); 1086bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1096bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1106bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis StoreManager &getStoreManager() { 1116bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getStoreManager(); 1126bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1137b73e0832b20af1f43601a3d19e76d02d9f4dce5Ted Kremenek 114a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks /// \brief Returns the previous node in the exploded graph, which includes 115a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks /// the state of the program before the checker ran. Note, checkers should 116a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks /// not retain the node in their state since the nodes might get invalidated. 11739ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks ExplodedNode *getPredecessor() { return Pred; } 1180a6e09f67c719c318856be19d57e19972101f62cJordan Rose const ProgramStateRef &getState() const { return Pred->getState(); } 1196bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 12057300760964904cc022a175643342f29f46b7e6bAnna Zaks /// \brief Check if the checker changed the state of the execution; ex: added 12157300760964904cc022a175643342f29f46b7e6bAnna Zaks /// a new transition or a bug report. 12257300760964904cc022a175643342f29f46b7e6bAnna Zaks bool isDifferent() { return Changed; } 12357300760964904cc022a175643342f29f46b7e6bAnna Zaks 1245d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks /// \brief Returns the number of times the current block has been visited 1255d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks /// along the analyzed path. 12666c486f275531df6362b3511fc3af6563561801bTed Kremenek unsigned blockCount() const { 12766c486f275531df6362b3511fc3af6563561801bTed Kremenek return NB.getContext().blockCount(); 128ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 1295d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks 1306bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ASTContext &getASTContext() { 1316bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getContext(); 1326bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 133461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks 1344e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie const LangOptions &getLangOpts() const { 1354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie return Eng.getContext().getLangOpts(); 136461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks } 137461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks 138eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks const LocationContext *getLocationContext() const { 13939ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks return Pred->getLocationContext(); 14039ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks } 14139ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks 142955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks const StackFrameContext *getStackFrame() const { 143955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks return Pred->getStackFrame(); 144c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks } 145c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks 146fadcd5d5bbe1bfc1c6b8d819cc2242f780a49fecAnna Zaks /// Return true if the current LocationContext has no caller context. 147fadcd5d5bbe1bfc1c6b8d819cc2242f780a49fecAnna Zaks bool inTopFrame() const { return getLocationContext()->inTopFrame(); } 148fadcd5d5bbe1bfc1c6b8d819cc2242f780a49fecAnna Zaks 1496bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis BugReporter &getBugReporter() { 1506bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getBugReporter(); 1516bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1526bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1536bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis SourceManager &getSourceManager() { 1546bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return getBugReporter().getSourceManager(); 1556bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1566bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1576bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis SValBuilder &getSValBuilder() { 1586bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getSValBuilder(); 1596bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1606bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1613f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks SymbolManager &getSymbolManager() { 1623f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks return getSValBuilder().getSymbolManager(); 1633f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks } 1643f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks 165eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks bool isObjCGCEnabled() const { 16617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose return Eng.isObjCGCEnabled(); 16717a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose } 16817a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose 1696a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks ProgramStateManager &getStateManager() { 1706a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks return Eng.getStateManager(); 1716a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks } 1726a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks 173063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 174063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks return Pred->getLocationContext()->getAnalysisDeclContext(); 175063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks } 176063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks 177ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /// \brief Get the blockID. 178ef8225444452a1486bd721f3285301fe84643b00Stephen Hines unsigned getBlockID() const { 179ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return NB.getContext().getBlock()->getBlockID(); 180ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 181ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 182ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /// \brief If the given node corresponds to a PostStore program point, 183ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /// retrieve the location region as it was uttered in the code. 1843d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// 1853d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// This utility can be useful for generating extensive diagnostics, for 1863d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks /// example, for finding variables that the given symbol was assigned to. 1873d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) { 1883d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks ProgramPoint L = N->getLocation(); 1897a95de68c093991047ed8d339479ccad51b88663David Blaikie if (Optional<PostStore> PSL = L.getAs<PostStore>()) 1903d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks return reinterpret_cast<const MemRegion*>(PSL->getLocationValue()); 1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1923d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks } 1933d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks 194c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks /// \brief Get the value of arbitrary expressions at this point in the path. 195c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks SVal getSVal(const Stmt *S) const { 196c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks return getState()->getSVal(S, getLocationContext()); 197c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks } 198c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks 1990bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// \brief Generates a new transition in the program state graph 2000bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// (ExplodedGraph). Uses the default CheckerContext predecessor node. 2010bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// 202fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose /// @param State The state of the generated node. If not specified, the state 203fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose /// will not be changed, but the new node will have the checker's tag. 2040bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// @param Tag The tag is used to uniquely identify the creation site. If no 2050bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// tag is specified, a default tag, unique to the given checker, 2060bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// will be used. Tags are used to prevent states generated at 2070bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// different sites from caching out. 2086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ExplodedNode *addTransition(ProgramStateRef State = nullptr, 2096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ProgramPointTag *Tag = nullptr) { 2106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return addTransitionImpl(State ? State : getState(), false, nullptr, Tag); 211063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks } 212063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks 2130bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// \brief Generates a new transition with the given predecessor. 2148ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// Allows checkers to generate a chain of nodes. 2150bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// 2160bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// @param State The state of the generated node. 2170bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// @param Pred The transition will be generated from the specified Pred node 2180bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// to the newly generated node. 2190bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks /// @param Tag The tag to uniquely identify the creation site. 2208bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ExplodedNode *addTransition(ProgramStateRef State, 221fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ExplodedNode *Pred, 2226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ProgramPointTag *Tag = nullptr) { 223fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose return addTransitionImpl(State, false, Pred, Tag); 2246bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 2256bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 226fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose /// \brief Generate a sink node. Generating a sink stops exploration of the 2278ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// given path. 2286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ExplodedNode *generateSink(ProgramStateRef State = nullptr, 2296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ExplodedNode *Pred = nullptr, 2306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ProgramPointTag *Tag = nullptr) { 231fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose return addTransitionImpl(State ? State : getState(), true, Pred, Tag); 2326bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 2336bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 234063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks /// \brief Emit the diagnostics report. 235785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose void emitReport(BugReport *R) { 23657300760964904cc022a175643342f29f46b7e6bAnna Zaks Changed = true; 237785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose Eng.getBugReporter().emitReport(R); 2386bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 2396bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 240b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks /// \brief Get the declaration of the called function (path-sensitive). 241b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks const FunctionDecl *getCalleeDecl(const CallExpr *CE) const; 242b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks 2430e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks /// \brief Get the name of the called function (path-sensitive). 2449b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks StringRef getCalleeName(const FunctionDecl *FunDecl) const; 2459b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks 2465ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks /// \brief Get the identifier of the called function (path-sensitive). 2475ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const { 2485ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks const FunctionDecl *FunDecl = getCalleeDecl(CE); 2495ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks if (FunDecl) 2505ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks return FunDecl->getIdentifier(); 2515ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks else 2526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2535ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks } 2545ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks 2559b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks /// \brief Get the name of the called function (path-sensitive). 2569b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks StringRef getCalleeName(const CallExpr *CE) const { 2579b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks const FunctionDecl *FunDecl = getCalleeDecl(CE); 2589b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks return getCalleeName(FunDecl); 2599b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks } 2609b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks 2612f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// \brief Returns true if the callee is an externally-visible function in the 2622f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// top-level namespace, such as \c malloc. 2632f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// 2642f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// If a name is provided, the function must additionally match the given 2652f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// name. 2662f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// 2672f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// Note that this deliberately excludes C++ library functions in the \c std 2682f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// namespace, but will include C library functions accessed through the 2692f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// \c std namespace. This also does not check if the function is declared 2702f3017f9cbd3774f690c979410bfec38423d03afJordan Rose /// as 'extern "C"', or if it uses C++ name mangling. 2712f3017f9cbd3774f690c979410bfec38423d03afJordan Rose static bool isCLibraryFunction(const FunctionDecl *FD, 2722f3017f9cbd3774f690c979410bfec38423d03afJordan Rose StringRef Name = StringRef()); 2730e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks 274461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// \brief Depending on wither the location corresponds to a macro, return 275461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// either the macro name or the token spelling. 276461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// 277461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// This could be useful when checkers' logic depends on whether a function 278461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// is called with a given macro argument. For example: 279461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// s = socket(AF_INET,..) 280461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// If AF_INET is a macro, the result should be treated as a source of taint. 281461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// 282461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName(). 283461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks StringRef getMacroNameOrSpelling(SourceLocation &Loc); 284461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks 2856bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisprivate: 2868bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ExplodedNode *addTransitionImpl(ProgramStateRef State, 28739ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks bool MarkAsSink, 2886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ExplodedNode *P = nullptr, 2896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ProgramPointTag *Tag = nullptr) { 290c8bb3befcad8cd8fc9556bc265289b07dc3c94c8Anna Zaks if (!State || (State == Pred->getState() && !Tag && !MarkAsSink)) 291df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks return Pred; 292df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks 29357300760964904cc022a175643342f29f46b7e6bAnna Zaks Changed = true; 294fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location); 295fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose if (!P) 296fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose P = Pred; 297fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose 298fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ExplodedNode *node; 299fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose if (MarkAsSink) 300fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose node = NB.generateSink(LocalLoc, State, P); 301fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose else 302fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose node = NB.generateNode(LocalLoc, State, P); 3036bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return node; 3046bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 3056bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis}; 3066bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 3076bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end GR namespace 3086bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 3096bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end clang namespace 3106bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 3116bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#endif 312