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