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