CheckerContext.h revision 5ac1df3e15f91ed663826faec7efe2462c18d98c
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"
195ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks#include "llvm/ADT/ImmutableMap.h"
205ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks
215ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks// Declare an immutable map suitable for placement into program states's GDM.
225ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks#define REGISTER_MAP_WITH_GDM(Map, Key, Value) \
235ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  typedef llvm::ImmutableMap<Key, Value> Map; \
245ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  namespace clang { \
255ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  namespace ento { \
265ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks    template <> \
275ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks    struct ProgramStateTrait<Map> \
285ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks      : public ProgramStatePartialTrait<Map> { \
295ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks      static void *GDMIndex() { static int Index; return &Index; } \
305ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks    }; \
315ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  } \
325ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  }
335ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks
346bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
356bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace clang {
366bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace ento {
376bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
386bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisclass CheckerContext {
396bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ExprEngine &Eng;
4057300760964904cc022a175643342f29f46b7e6bAnna Zaks  /// The current exploded(symbolic execution) graph node.
416bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ExplodedNode *Pred;
4257300760964904cc022a175643342f29f46b7e6bAnna Zaks  /// The flag is true if the (state of the execution) has been modified
4357300760964904cc022a175643342f29f46b7e6bAnna Zaks  /// by the checker using this context. For example, a new transition has been
4457300760964904cc022a175643342f29f46b7e6bAnna Zaks  /// added or a bug report issued.
4557300760964904cc022a175643342f29f46b7e6bAnna Zaks  bool Changed;
4657300760964904cc022a175643342f29f46b7e6bAnna Zaks  /// The tagged location, which is used to generate all new nodes.
473f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks  const ProgramPoint Location;
483152b3cb5b6a2f797d0972c81a5eb3fd69c0d620Anna Zaks  NodeBuilder &NB;
49063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks
506bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidispublic:
51514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek  /// If we are post visiting a call, this flag will be set if the
52514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek  /// call was inlined.  In all other cases it will be false.
53514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek  const bool wasInlined;
54514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek
558ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks  CheckerContext(NodeBuilder &builder,
5618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                 ExprEngine &eng,
5718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                 ExplodedNode *pred,
58514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                 const ProgramPoint &loc,
59514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                 bool wasInlined = false)
608ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks    : Eng(eng),
6118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek      Pred(pred),
6257300760964904cc022a175643342f29f46b7e6bAnna Zaks      Changed(false),
633f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks      Location(loc),
64514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek      NB(builder),
65514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek      wasInlined(wasInlined) {
66777d706547ebc751d998134774d9d5388fff8e02Anna Zaks    assert(Pred->getState() &&
67777d706547ebc751d998134774d9d5388fff8e02Anna Zaks           "We should not call the checkers on an empty state.");
68777d706547ebc751d998134774d9d5388fff8e02Anna Zaks  }
696bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
706bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  AnalysisManager &getAnalysisManager() {
716bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getAnalysisManager();
726bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
736bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
746bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ConstraintManager &getConstraintManager() {
756bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getConstraintManager();
766bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
776bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
786bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  StoreManager &getStoreManager() {
796bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getStoreManager();
806bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
816bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
82255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek  const AnalyzerOptions::ConfigTable &getConfig() const {
83255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    return Eng.getAnalysisManager().options.Config;
847b73e0832b20af1f43601a3d19e76d02d9f4dce5Ted Kremenek  }
857b73e0832b20af1f43601a3d19e76d02d9f4dce5Ted Kremenek
86a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks  /// \brief Returns the previous node in the exploded graph, which includes
87a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks  /// the state of the program before the checker ran. Note, checkers should
88a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks  /// not retain the node in their state since the nodes might get invalidated.
8939ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks  ExplodedNode *getPredecessor() { return Pred; }
908bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef getState() const { return Pred->getState(); }
916bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
9257300760964904cc022a175643342f29f46b7e6bAnna Zaks  /// \brief Check if the checker changed the state of the execution; ex: added
9357300760964904cc022a175643342f29f46b7e6bAnna Zaks  /// a new transition or a bug report.
9457300760964904cc022a175643342f29f46b7e6bAnna Zaks  bool isDifferent() { return Changed; }
9557300760964904cc022a175643342f29f46b7e6bAnna Zaks
965d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks  /// \brief Returns the number of times the current block has been visited
975d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks  /// along the analyzed path.
9866c486f275531df6362b3511fc3af6563561801bTed Kremenek  unsigned blockCount() const {
9966c486f275531df6362b3511fc3af6563561801bTed Kremenek    return NB.getContext().blockCount();
100ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  }
1015d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks
1026bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ASTContext &getASTContext() {
1036bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getContext();
1046bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
105461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
1064e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  const LangOptions &getLangOpts() const {
1074e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    return Eng.getContext().getLangOpts();
108461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  }
109461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
110eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks  const LocationContext *getLocationContext() const {
11139ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks    return Pred->getLocationContext();
11239ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks  }
11339ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks
114955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks  const StackFrameContext *getStackFrame() const {
115955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks    return Pred->getStackFrame();
116c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks  }
117c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks
11805fcbd3dc28f4cba4a6d33e7aeaabb5f6f7837e3Anna Zaks  /// Returns true if the predecessor is within an inlined function/method.
11905fcbd3dc28f4cba4a6d33e7aeaabb5f6f7837e3Anna Zaks  bool isWithinInlined() {
120dc601f4a9f69315521abddbca04d4652deee5fdbAnna Zaks    return (getStackFrame()->getParent() != 0);
12105fcbd3dc28f4cba4a6d33e7aeaabb5f6f7837e3Anna Zaks  }
12205fcbd3dc28f4cba4a6d33e7aeaabb5f6f7837e3Anna Zaks
1236bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  BugReporter &getBugReporter() {
1246bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getBugReporter();
1256bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1266bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
1276bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  SourceManager &getSourceManager() {
1286bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return getBugReporter().getSourceManager();
1296bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1306bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
1316bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  SValBuilder &getSValBuilder() {
1326bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getSValBuilder();
1336bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1346bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
1353f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks  SymbolManager &getSymbolManager() {
1363f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks    return getSValBuilder().getSymbolManager();
1373f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks  }
1383f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks
139eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks  bool isObjCGCEnabled() const {
14017a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose    return Eng.isObjCGCEnabled();
14117a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose  }
14217a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose
1436a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks  ProgramStateManager &getStateManager() {
1446a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks    return Eng.getStateManager();
1456a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks  }
1466a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks
147063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
148063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks    return Pred->getLocationContext()->getAnalysisDeclContext();
149063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  }
150063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks
1513d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// \brief If the given node corresponds to a PostStore program point, retrieve
1523d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// the location region as it was uttered in the code.
1533d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  ///
1543d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// This utility can be useful for generating extensive diagnostics, for
1553d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  /// example, for finding variables that the given symbol was assigned to.
1563d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
1573d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    ProgramPoint L = N->getLocation();
1583d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    if (const PostStore *PSL = dyn_cast<PostStore>(&L))
1593d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks      return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
1603d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks    return 0;
1613d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks  }
1623d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks
163c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks  /// \brief Get the value of arbitrary expressions at this point in the path.
164c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks  SVal getSVal(const Stmt *S) const {
165c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks    return getState()->getSVal(S, getLocationContext());
166c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks  }
167c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks
1680bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// \brief Generates a new transition in the program state graph
1690bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
1700bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///
171fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose  /// @param State The state of the generated node. If not specified, the state
172fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose  ///        will not be changed, but the new node will have the checker's tag.
1730bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param Tag The tag is used to uniquely identify the creation site. If no
1740bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///        tag is specified, a default tag, unique to the given checker,
1750bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///        will be used. Tags are used to prevent states generated at
1760bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///        different sites from caching out.
177fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose  ExplodedNode *addTransition(ProgramStateRef State = 0,
1780bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks                              const ProgramPointTag *Tag = 0) {
179fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    return addTransitionImpl(State ? State : getState(), false, 0, Tag);
180063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  }
181063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks
1820bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// \brief Generates a new transition with the given predecessor.
1838ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks  /// Allows checkers to generate a chain of nodes.
1840bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///
1850bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param State The state of the generated node.
1860bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param Pred The transition will be generated from the specified Pred node
1870bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///             to the newly generated node.
1880bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param Tag The tag to uniquely identify the creation site.
1898bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ExplodedNode *addTransition(ProgramStateRef State,
190fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                              ExplodedNode *Pred,
191fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                              const ProgramPointTag *Tag = 0) {
192fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    return addTransitionImpl(State, false, Pred, Tag);
1936bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1946bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
195fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose  /// \brief Generate a sink node. Generating a sink stops exploration of the
1968ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks  /// given path.
197fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose  ExplodedNode *generateSink(ProgramStateRef State = 0,
198fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                             ExplodedNode *Pred = 0,
199fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose                             const ProgramPointTag *Tag = 0) {
200fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
2016bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
2026bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
203063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  /// \brief Emit the diagnostics report.
2046bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  void EmitReport(BugReport *R) {
20557300760964904cc022a175643342f29f46b7e6bAnna Zaks    Changed = true;
2066bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    Eng.getBugReporter().EmitReport(R);
2076bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
2086bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
209b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks  /// \brief Get the declaration of the called function (path-sensitive).
210b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
211b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks
2120e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks  /// \brief Get the name of the called function (path-sensitive).
2139b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  StringRef getCalleeName(const FunctionDecl *FunDecl) const;
2149b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2155ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  /// \brief Get the identifier of the called function (path-sensitive).
2165ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const {
2175ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks    const FunctionDecl *FunDecl = getCalleeDecl(CE);
2185ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks    if (FunDecl)
2195ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks      return FunDecl->getIdentifier();
2205ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks    else
2215ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks      return 0;
2225ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks  }
2235ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks
2249b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  /// \brief Get the name of the called function (path-sensitive).
2259b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  StringRef getCalleeName(const CallExpr *CE) const {
2269b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    const FunctionDecl *FunDecl = getCalleeDecl(CE);
2279b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    return getCalleeName(FunDecl);
2289b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  }
2299b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2309b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  /// Given a function declaration and a name checks if this is a C lib
2319b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  /// function with the given name.
2329b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name);
233e00575f12cf280621ef0ed4d69e909bdfc9fef62Anna Zaks  static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name,
234e00575f12cf280621ef0ed4d69e909bdfc9fef62Anna Zaks                                 ASTContext &Context);
2350e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks
236461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// \brief Depending on wither the location corresponds to a macro, return
237461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// either the macro name or the token spelling.
238461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  ///
239461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// This could be useful when checkers' logic depends on whether a function
240461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// is called with a given macro argument. For example:
241461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  ///   s = socket(AF_INET,..)
242461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// If AF_INET is a macro, the result should be treated as a source of taint.
243461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  ///
244461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
245461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  StringRef getMacroNameOrSpelling(SourceLocation &Loc);
246461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
2476bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisprivate:
2488bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ExplodedNode *addTransitionImpl(ProgramStateRef State,
24939ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                 bool MarkAsSink,
25039ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                 ExplodedNode *P = 0,
25139ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                 const ProgramPointTag *Tag = 0) {
252c8bb3befcad8cd8fc9556bc265289b07dc3c94c8Anna Zaks    if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
253df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks      return Pred;
254df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks
25557300760964904cc022a175643342f29f46b7e6bAnna Zaks    Changed = true;
256fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
257fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    if (!P)
258fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      P = Pred;
259fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose
260fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    ExplodedNode *node;
261fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    if (MarkAsSink)
262fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      node = NB.generateSink(LocalLoc, State, P);
263fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose    else
264fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose      node = NB.generateNode(LocalLoc, State, P);
2656bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return node;
2666bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
2676bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis};
2686bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
26957300760964904cc022a175643342f29f46b7e6bAnna Zaks/// \brief A helper class which wraps a boolean value set to false by default.
27057300760964904cc022a175643342f29f46b7e6bAnna Zaksstruct DefaultBool {
27157300760964904cc022a175643342f29f46b7e6bAnna Zaks  bool Val;
27257300760964904cc022a175643342f29f46b7e6bAnna Zaks  DefaultBool() : Val(false) {}
27357300760964904cc022a175643342f29f46b7e6bAnna Zaks  operator bool() const { return Val; }
27457300760964904cc022a175643342f29f46b7e6bAnna Zaks  DefaultBool &operator=(bool b) { Val = b; return *this; }
27557300760964904cc022a175643342f29f46b7e6bAnna Zaks};
27657300760964904cc022a175643342f29f46b7e6bAnna Zaks
2776bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end GR namespace
2786bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
2796bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end clang namespace
2806bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
2816bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#endif
282