clang  8.0.0svn
CheckerContext.h
Go to the documentation of this file.
1 //== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines CheckerContext that provides contextual info for
11 // path-sensitive checkers.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
16 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
17 
20 
21 namespace clang {
22 namespace ento {
23 
25  ExprEngine &Eng;
26  /// The current exploded(symbolic execution) graph node.
27  ExplodedNode *Pred;
28  /// The flag is true if the (state of the execution) has been modified
29  /// by the checker using this context. For example, a new transition has been
30  /// added or a bug report issued.
31  bool Changed;
32  /// The tagged location, which is used to generate all new nodes.
33  const ProgramPoint Location;
34  NodeBuilder &NB;
35 
36 public:
37  /// If we are post visiting a call, this flag will be set if the
38  /// call was inlined. In all other cases it will be false.
39  const bool wasInlined;
40 
42  ExprEngine &eng,
43  ExplodedNode *pred,
44  const ProgramPoint &loc,
45  bool wasInlined = false)
46  : Eng(eng),
47  Pred(pred),
48  Changed(false),
49  Location(loc),
50  NB(builder),
51  wasInlined(wasInlined) {
52  assert(Pred->getState() &&
53  "We should not call the checkers on an empty state.");
54  }
55 
57  return Eng.getAnalysisManager();
58  }
59 
61  return Eng.getConstraintManager();
62  }
63 
65  return Eng.getStoreManager();
66  }
67 
68  /// Returns the previous node in the exploded graph, which includes
69  /// the state of the program before the checker ran. Note, checkers should
70  /// not retain the node in their state since the nodes might get invalidated.
71  ExplodedNode *getPredecessor() { return Pred; }
72  const ProgramStateRef &getState() const { return Pred->getState(); }
73 
74  /// Check if the checker changed the state of the execution; ex: added
75  /// a new transition or a bug report.
76  bool isDifferent() { return Changed; }
77 
78  /// Returns the number of times the current block has been visited
79  /// along the analyzed path.
80  unsigned blockCount() const {
81  return NB.getContext().blockCount();
82  }
83 
85  return Eng.getContext();
86  }
87 
88  const LangOptions &getLangOpts() const {
89  return Eng.getContext().getLangOpts();
90  }
91 
93  return Pred->getLocationContext();
94  }
95 
97  return Pred->getStackFrame();
98  }
99 
100  /// Return true if the current LocationContext has no caller context.
101  bool inTopFrame() const { return getLocationContext()->inTopFrame(); }
102 
104  return Eng.getBugReporter();
105  }
106 
108  return getBugReporter().getSourceManager();
109  }
110 
112  return Eng.getSValBuilder();
113  }
114 
116  return getSValBuilder().getSymbolManager();
117  }
118 
120  return Eng.getStateManager();
121  }
122 
124  return Pred->getLocationContext()->getAnalysisDeclContext();
125  }
126 
127  /// Get the blockID.
128  unsigned getBlockID() const {
129  return NB.getContext().getBlock()->getBlockID();
130  }
131 
132  /// If the given node corresponds to a PostStore program point,
133  /// retrieve the location region as it was uttered in the code.
134  ///
135  /// This utility can be useful for generating extensive diagnostics, for
136  /// example, for finding variables that the given symbol was assigned to.
138  ProgramPoint L = N->getLocation();
139  if (Optional<PostStore> PSL = L.getAs<PostStore>())
140  return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
141  return nullptr;
142  }
143 
144  /// Get the value of arbitrary expressions at this point in the path.
145  SVal getSVal(const Stmt *S) const {
146  return Pred->getSVal(S);
147  }
148 
149  /// Returns true if the value of \p E is greater than or equal to \p
150  /// Val under unsigned comparison
151  bool isGreaterOrEqual(const Expr *E, unsigned long long Val);
152 
153  /// Returns true if the value of \p E is negative.
154  bool isNegative(const Expr *E);
155 
156  /// Generates a new transition in the program state graph
157  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
158  ///
159  /// @param State The state of the generated node. If not specified, the state
160  /// will not be changed, but the new node will have the checker's tag.
161  /// @param Tag The tag is used to uniquely identify the creation site. If no
162  /// tag is specified, a default tag, unique to the given checker,
163  /// will be used. Tags are used to prevent states generated at
164  /// different sites from caching out.
166  const ProgramPointTag *Tag = nullptr) {
167  return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
168  }
169 
170  /// Generates a new transition with the given predecessor.
171  /// Allows checkers to generate a chain of nodes.
172  ///
173  /// @param State The state of the generated node.
174  /// @param Pred The transition will be generated from the specified Pred node
175  /// to the newly generated node.
176  /// @param Tag The tag to uniquely identify the creation site.
178  ExplodedNode *Pred,
179  const ProgramPointTag *Tag = nullptr) {
180  return addTransitionImpl(State, false, Pred, Tag);
181  }
182 
183  /// Generate a sink node. Generating a sink stops exploration of the
184  /// given path. To create a sink node for the purpose of reporting an error,
185  /// checkers should use generateErrorNode() instead.
187  const ProgramPointTag *Tag = nullptr) {
188  return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
189  }
190 
191  /// Generate a transition to a node that will be used to report
192  /// an error. This node will be a sink. That is, it will stop exploration of
193  /// the given path.
194  ///
195  /// @param State The state of the generated node.
196  /// @param Tag The tag to uniquely identify the creation site. If null,
197  /// the default tag for the checker will be used.
199  const ProgramPointTag *Tag = nullptr) {
200  return generateSink(State, Pred,
201  (Tag ? Tag : Location.getTag()));
202  }
203 
204  /// Generate a transition to a node that will be used to report
205  /// an error. This node will not be a sink. That is, exploration will
206  /// continue along this path.
207  ///
208  /// @param State The state of the generated node.
209  /// @param Tag The tag to uniquely identify the creation site. If null,
210  /// the default tag for the checker will be used.
211  ExplodedNode *
213  const ProgramPointTag *Tag = nullptr) {
214  return addTransition(State, (Tag ? Tag : Location.getTag()));
215  }
216 
217  /// Emit the diagnostics report.
218  void emitReport(std::unique_ptr<BugReport> R) {
219  Changed = true;
220  Eng.getBugReporter().emitReport(std::move(R));
221  }
222 
223  /// Returns the word that should be used to refer to the declaration
224  /// in the report.
225  StringRef getDeclDescription(const Decl *D);
226 
227  /// Get the declaration of the called function (path-sensitive).
228  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
229 
230  /// Get the name of the called function (path-sensitive).
231  StringRef getCalleeName(const FunctionDecl *FunDecl) const;
232 
233  /// Get the identifier of the called function (path-sensitive).
234  const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const {
235  const FunctionDecl *FunDecl = getCalleeDecl(CE);
236  if (FunDecl)
237  return FunDecl->getIdentifier();
238  else
239  return nullptr;
240  }
241 
242  /// Get the name of the called function (path-sensitive).
243  StringRef getCalleeName(const CallExpr *CE) const {
244  const FunctionDecl *FunDecl = getCalleeDecl(CE);
245  return getCalleeName(FunDecl);
246  }
247 
248  /// Returns true if the callee is an externally-visible function in the
249  /// top-level namespace, such as \c malloc.
250  ///
251  /// If a name is provided, the function must additionally match the given
252  /// name.
253  ///
254  /// Note that this deliberately excludes C++ library functions in the \c std
255  /// namespace, but will include C library functions accessed through the
256  /// \c std namespace. This also does not check if the function is declared
257  /// as 'extern "C"', or if it uses C++ name mangling.
258  static bool isCLibraryFunction(const FunctionDecl *FD,
259  StringRef Name = StringRef());
260 
261  /// Depending on wither the location corresponds to a macro, return
262  /// either the macro name or the token spelling.
263  ///
264  /// This could be useful when checkers' logic depends on whether a function
265  /// is called with a given macro argument. For example:
266  /// s = socket(AF_INET,..)
267  /// If AF_INET is a macro, the result should be treated as a source of taint.
268  ///
269  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
271 
272 private:
273  ExplodedNode *addTransitionImpl(ProgramStateRef State,
274  bool MarkAsSink,
275  ExplodedNode *P = nullptr,
276  const ProgramPointTag *Tag = nullptr) {
277  // The analyzer may stop exploring if it sees a state it has previously
278  // visited ("cache out"). The early return here is a defensive check to
279  // prevent accidental caching out by checker API clients. Unless there is a
280  // tag or the client checker has requested that the generated node be
281  // marked as a sink, we assume that a client requesting a transition to a
282  // state that is the same as the predecessor state has made a mistake. We
283  // return the predecessor rather than cache out.
284  //
285  // TODO: We could potentially change the return to an assertion to alert
286  // clients to their mistake, but several checkers (including
287  // DereferenceChecker, CallAndMessageChecker, and DynamicTypePropagation)
288  // rely upon the defensive behavior and would need to be updated.
289  if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
290  return Pred;
291 
292  Changed = true;
293  const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
294  if (!P)
295  P = Pred;
296 
297  ExplodedNode *node;
298  if (MarkAsSink)
299  node = NB.generateSink(LocalLoc, State, P);
300  else
301  node = NB.generateNode(LocalLoc, State, P);
302  return node;
303  }
304 };
305 
306 } // end GR namespace
307 
308 } // end clang namespace
309 
310 #endif
Represents a function declaration or definition.
Definition: Decl.h:1732
StringRef getCalleeName(const CallExpr *CE) const
Get the name of the called function (path-sensitive).
SymbolManager & getSymbolManager()
Definition: SValBuilder.h:172
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
Definition: CoreEngine.h:212
Stmt - This represents one statement.
Definition: Stmt.h:66
unsigned getBlockID() const
Definition: CFG.h:856
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
StringRef P
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
Definition: ProgramPoint.h:134
StringRef getDeclDescription(const Decl *D)
Returns the word that should be used to refer to the declaration in the report.
AnalysisManager & getAnalysisManager()
const ProgramStateRef & getState() const
CheckerContext(NodeBuilder &builder, ExprEngine &eng, ExplodedNode *pred, const ProgramPoint &loc, bool wasInlined=false)
const FunctionDecl * getCalleeDecl(const CallExpr *CE) const
Get the declaration of the called function (path-sensitive).
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
const bool wasInlined
If we are post visiting a call, this flag will be set if the call was inlined.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:269
StringRef getCalleeName(const FunctionDecl *FunDecl) const
Get the name of the called function (path-sensitive).
One of these records is kept for each identifier that is lexed.
bool isGreaterOrEqual(const Expr *E, unsigned long long Val)
Returns true if the value of E is greater than or equal to Val under unsigned comparison.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
LineState State
AnalysisDeclContext contains the context data for the function or method under analysis.
Represents a program point after a store evaluation.
Definition: ProgramPoint.h:433
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
BugReporter & getBugReporter()
void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
ProgramStateManager & getStateManager()
const LocationContext * getLocationContext() const
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const IdentifierInfo * getCalleeIdentifier(const CallExpr *CE) const
Get the identifier of the called function (path-sensitive).
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Definition: CoreEngine.h:292
This represents one expression.
Definition: Expr.h:106
static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name=StringRef())
Returns true if the callee is an externally-visible function in the top-level namespace, such as malloc.
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition: CoreEngine.h:228
ExplodedNode * addTransition(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generates a new transition with the given predecessor.
SymbolManager & getSymbolManager()
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition: ExprEngine.h:179
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
ConstraintManager & getConstraintManager()
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
BugReporter is a utility class for generating PathDiagnostics for analysis.
Definition: BugReporter.h:412
#define false
Definition: stdbool.h:33
StoreManager & getStoreManager()
Encodes a location in the source.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
Definition: ProgramPoint.h:40
AnalysisManager & getAnalysisManager() override
Definition: ExprEngine.h:181
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:76
BugReporter & getBugReporter()
Definition: ExprEngine.h:189
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path...
unsigned getBlockID() const
Get the blockID.
Dataflow Directional Tag Classes.
SValBuilder & getSValBuilder()
Definition: ExprEngine.h:187
StoreManager & getStoreManager()
Definition: ExprEngine.h:379
const NodeBuilderContext & getContext()
Definition: CoreEngine.h:318
StringRef getMacroNameOrSpelling(SourceLocation &Loc)
Depending on wither the location corresponds to a macro, return either the macro name or the token sp...
const ProgramPointTag * getTag() const
Definition: ProgramPoint.h:179
ProgramStateManager & getStateManager() override
Definition: ExprEngine.h:377
const StackFrameContext * getStackFrame() const
const ProgramStateRef & getState() const
bool isNegative(const Expr *E)
Returns true if the value of E is negative.
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Definition: CoreEngine.h:281
SourceManager & getSourceManager()
Definition: BugReporter.h:474
AnalysisDeclContext * getCurrentAnalysisDeclContext() const
SourceManager & getSourceManager()
SValBuilder & getSValBuilder()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2405
static const MemRegion * getLocationRegionIfPostStore(const ExplodedNode *N)
If the given node corresponds to a PostStore program point, retrieve the location region as it was ut...
const StackFrameContext * getStackFrame() const
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:153
ConstraintManager & getConstraintManager()
Definition: ExprEngine.h:381
bool inTopFrame() const
Return true if the current LocationContext has no caller context.
AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getLocationContext() const
bool isDifferent()
Check if the checker changed the state of the execution; ex: added a new transition or a bug report...
const LangOptions & getLangOpts() const
Definition: ASTContext.h:706
This class handles loading and caching of source files into memory.
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
Definition: CoreEngine.h:208
const LangOptions & getLangOpts() const