CheckerContext.h revision 461af1e502c9bd88330bbf17d449a7593fc0d624
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"
196bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
206bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace clang {
216bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace ento {
226bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
236bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisclass CheckerContext {
246bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ExprEngine &Eng;
256bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ExplodedNode *Pred;
263f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks  const ProgramPoint Location;
273152b3cb5b6a2f797d0972c81a5eb3fd69c0d620Anna Zaks  NodeBuilder &NB;
28063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks
296bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidispublic:
308ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks  CheckerContext(NodeBuilder &builder,
3118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                 ExprEngine &eng,
3218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                 ExplodedNode *pred,
33063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks                 const ProgramPoint &loc)
348ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks    : Eng(eng),
3518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek      Pred(pred),
363f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks      Location(loc),
37777d706547ebc751d998134774d9d5388fff8e02Anna Zaks      NB(builder) {
38777d706547ebc751d998134774d9d5388fff8e02Anna Zaks    assert(Pred->getState() &&
39777d706547ebc751d998134774d9d5388fff8e02Anna Zaks           "We should not call the checkers on an empty state.");
40777d706547ebc751d998134774d9d5388fff8e02Anna Zaks  }
416bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
426bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  AnalysisManager &getAnalysisManager() {
436bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getAnalysisManager();
446bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
456bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
466bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ConstraintManager &getConstraintManager() {
476bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getConstraintManager();
486bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
496bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
506bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  StoreManager &getStoreManager() {
516bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getStoreManager();
526bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
536bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
54a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks  /// \brief Returns the previous node in the exploded graph, which includes
55a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks  /// the state of the program before the checker ran. Note, checkers should
56a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks  /// not retain the node in their state since the nodes might get invalidated.
5739ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks  ExplodedNode *getPredecessor() { return Pred; }
58eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks  const ProgramState *getState() const { return Pred->getState(); }
596bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
605d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks  /// \brief Returns the number of times the current block has been visited
615d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks  /// along the analyzed path.
62eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks  unsigned getCurrentBlockCount() const {
63ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks    return NB.getContext().getCurrentBlockCount();
64ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks  }
655d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks
666bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  ASTContext &getASTContext() {
676bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getContext();
686bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
69461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
70461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  const LangOptions &getLangOptions() const {
71461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks    return Eng.getContext().getLangOptions();
72461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  }
73461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
74eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks  const LocationContext *getLocationContext() const {
7539ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks    return Pred->getLocationContext();
7639ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks  }
7739ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks
786bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  BugReporter &getBugReporter() {
796bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getBugReporter();
806bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
816bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
826bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  SourceManager &getSourceManager() {
836bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return getBugReporter().getSourceManager();
846bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
856bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
866bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  SValBuilder &getSValBuilder() {
876bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return Eng.getSValBuilder();
886bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
896bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
903f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks  SymbolManager &getSymbolManager() {
913f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks    return getSValBuilder().getSymbolManager();
923f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks  }
933f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks
94eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks  bool isObjCGCEnabled() const {
9517a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose    return Eng.isObjCGCEnabled();
9617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose  }
9717a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose
986a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks  ProgramStateManager &getStateManager() {
996a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks    return Eng.getStateManager();
1006a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks  }
1016a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks
102063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
103063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks    return Pred->getLocationContext()->getAnalysisDeclContext();
104063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  }
105063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks
1060bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// \brief Generates a new transition in the program state graph
1070bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
1080bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///
1090bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param State The state of the generated node.
1100bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param Tag The tag is used to uniquely identify the creation site. If no
1110bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///        tag is specified, a default tag, unique to the given checker,
1120bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///        will be used. Tags are used to prevent states generated at
1130bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///        different sites from caching out.
1140bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ExplodedNode *addTransition(const ProgramState *State,
1150bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks                              const ProgramPointTag *Tag = 0) {
1160bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks    return addTransitionImpl(State, false, 0, Tag);
1176bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1180bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks
1190bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// \brief Generates a default transition (containing checker tag but no
1200bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// checker state changes).
1210bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ExplodedNode *addTransition() {
1220bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks    return addTransition(getState());
123063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  }
124063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks
1250bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// \brief Generates a new transition with the given predecessor.
1268ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks  /// Allows checkers to generate a chain of nodes.
1270bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///
1280bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param State The state of the generated node.
1290bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param Pred The transition will be generated from the specified Pred node
1300bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///             to the newly generated node.
1310bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param Tag The tag to uniquely identify the creation site.
1320bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  /// @param IsSink Mark the new node as sink, which will stop exploration of
1330bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ///               the given path.
1340bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks  ExplodedNode *addTransition(const ProgramState *State,
1350bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks                             ExplodedNode *Pred,
1360bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks                             const ProgramPointTag *Tag = 0,
1370bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks                             bool IsSink = false) {
1380bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks    return addTransitionImpl(State, IsSink, Pred, Tag);
1396bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1406bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
1418ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks  /// \brief Generate a sink node. Generating sink stops exploration of the
1428ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks  /// given path.
14318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  ExplodedNode *generateSink(const ProgramState *state = 0) {
1440bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks    return addTransitionImpl(state ? state : getState(), true);
1456bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1466bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
147063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks  /// \brief Emit the diagnostics report.
1486bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  void EmitReport(BugReport *R) {
1496bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    Eng.getBugReporter().EmitReport(R);
1506bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1516bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
152b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks  /// \brief Get the declaration of the called function (path-sensitive).
153b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
154b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks
1550e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks  /// \brief Get the name of the called function (path-sensitive).
1569b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  StringRef getCalleeName(const FunctionDecl *FunDecl) const;
1579b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
1589b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  /// \brief Get the name of the called function (path-sensitive).
1599b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  StringRef getCalleeName(const CallExpr *CE) const {
1609b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    const FunctionDecl *FunDecl = getCalleeDecl(CE);
1619b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    return getCalleeName(FunDecl);
1629b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  }
1639b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
1649b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  /// Given a function declaration and a name checks if this is a C lib
1659b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  /// function with the given name.
1669b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name);
1670e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks
168461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// \brief Depending on wither the location corresponds to a macro, return
169461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// either the macro name or the token spelling.
170461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  ///
171461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// This could be useful when checkers' logic depends on whether a function
172461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// is called with a given macro argument. For example:
173461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  ///   s = socket(AF_INET,..)
174461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// If AF_INET is a macro, the result should be treated as a source of taint.
175461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  ///
176461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
177461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks  StringRef getMacroNameOrSpelling(SourceLocation &Loc);
178461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
1796bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisprivate:
18039ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks  ExplodedNode *addTransitionImpl(const ProgramState *State,
18139ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                 bool MarkAsSink,
18239ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                 ExplodedNode *P = 0,
18339ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                 const ProgramPointTag *Tag = 0) {
18439ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks    assert(State);
185df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks    if (State == Pred->getState() && !Tag && !MarkAsSink)
186df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks      return Pred;
187df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks
18839ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks    ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location,
18939ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                        State,
19039ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks                                        P ? P : Pred, MarkAsSink);
1916bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis    return node;
1926bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis  }
1936bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis};
1946bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
1956bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end GR namespace
1966bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
1976bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end clang namespace
1986bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis
1996bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#endif
200