clang  7.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 
24  /// Declares an immutable map of type \p NameTy, suitable for placement into
25  /// the ProgramState. This is implementing using llvm::ImmutableMap.
26  ///
27  /// \code
28  /// State = State->set<Name>(K, V);
29  /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map.
30  /// State = State->remove<Name>(K);
31  /// NameTy Map = State->get<Name>();
32  /// \endcode
33  ///
34  /// The macro should not be used inside namespaces, or for traits that must
35  /// be accessible from more than one translation unit.
36  #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \
37  REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \
38  CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value))
39 
40  /// Declares an immutable set of type \p NameTy, suitable for placement into
41  /// the ProgramState. This is implementing using llvm::ImmutableSet.
42  ///
43  /// \code
44  /// State = State->add<Name>(E);
45  /// State = State->remove<Name>(E);
46  /// bool Present = State->contains<Name>(E);
47  /// NameTy Set = State->get<Name>();
48  /// \endcode
49  ///
50  /// The macro should not be used inside namespaces, or for traits that must
51  /// be accessible from more than one translation unit.
52  #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \
53  REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>)
54 
55  /// Declares an immutable list of type \p NameTy, suitable for placement into
56  /// the ProgramState. This is implementing using llvm::ImmutableList.
57  ///
58  /// \code
59  /// State = State->add<Name>(E); // Adds to the /end/ of the list.
60  /// bool Present = State->contains<Name>(E);
61  /// NameTy List = State->get<Name>();
62  /// \endcode
63  ///
64  /// The macro should not be used inside namespaces, or for traits that must
65  /// be accessible from more than one translation unit.
66  #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \
67  REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>)
68 
69 
71  ExprEngine &Eng;
72  /// The current exploded(symbolic execution) graph node.
73  ExplodedNode *Pred;
74  /// The flag is true if the (state of the execution) has been modified
75  /// by the checker using this context. For example, a new transition has been
76  /// added or a bug report issued.
77  bool Changed;
78  /// The tagged location, which is used to generate all new nodes.
79  const ProgramPoint Location;
80  NodeBuilder &NB;
81 
82 public:
83  /// If we are post visiting a call, this flag will be set if the
84  /// call was inlined. In all other cases it will be false.
85  const bool wasInlined;
86 
88  ExprEngine &eng,
89  ExplodedNode *pred,
90  const ProgramPoint &loc,
91  bool wasInlined = false)
92  : Eng(eng),
93  Pred(pred),
94  Changed(false),
95  Location(loc),
96  NB(builder),
97  wasInlined(wasInlined) {
98  assert(Pred->getState() &&
99  "We should not call the checkers on an empty state.");
100  }
101 
103  return Eng.getAnalysisManager();
104  }
105 
107  return Eng.getConstraintManager();
108  }
109 
111  return Eng.getStoreManager();
112  }
113 
114  /// \brief Returns the previous node in the exploded graph, which includes
115  /// the state of the program before the checker ran. Note, checkers should
116  /// not retain the node in their state since the nodes might get invalidated.
117  ExplodedNode *getPredecessor() { return Pred; }
118  const ProgramStateRef &getState() const { return Pred->getState(); }
119 
120  /// \brief Check if the checker changed the state of the execution; ex: added
121  /// a new transition or a bug report.
122  bool isDifferent() { return Changed; }
123 
124  /// \brief Returns the number of times the current block has been visited
125  /// along the analyzed path.
126  unsigned blockCount() const {
127  return NB.getContext().blockCount();
128  }
129 
131  return Eng.getContext();
132  }
133 
134  const LangOptions &getLangOpts() const {
135  return Eng.getContext().getLangOpts();
136  }
137 
139  return Pred->getLocationContext();
140  }
141 
143  return Pred->getStackFrame();
144  }
145 
146  /// Return true if the current LocationContext has no caller context.
147  bool inTopFrame() const { return getLocationContext()->inTopFrame(); }
148 
150  return Eng.getBugReporter();
151  }
152 
154  return getBugReporter().getSourceManager();
155  }
156 
158  return Eng.getSValBuilder();
159  }
160 
162  return getSValBuilder().getSymbolManager();
163  }
164 
165  bool isObjCGCEnabled() const {
166  return Eng.isObjCGCEnabled();
167  }
168 
170  return Eng.getStateManager();
171  }
172 
174  return Pred->getLocationContext()->getAnalysisDeclContext();
175  }
176 
177  /// \brief Get the blockID.
178  unsigned getBlockID() const {
179  return NB.getContext().getBlock()->getBlockID();
180  }
181 
182  /// \brief If the given node corresponds to a PostStore program point,
183  /// retrieve the location region as it was uttered in the code.
184  ///
185  /// This utility can be useful for generating extensive diagnostics, for
186  /// example, for finding variables that the given symbol was assigned to.
188  ProgramPoint L = N->getLocation();
189  if (Optional<PostStore> PSL = L.getAs<PostStore>())
190  return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
191  return nullptr;
192  }
193 
194  /// \brief Get the value of arbitrary expressions at this point in the path.
195  SVal getSVal(const Stmt *S) const {
196  return Pred->getSVal(S);
197  }
198 
199  /// \brief Returns true if the value of \p E is greater than or equal to \p
200  /// Val under unsigned comparison
201  bool isGreaterOrEqual(const Expr *E, unsigned long long Val);
202 
203  /// Returns true if the value of \p E is negative.
204  bool isNegative(const Expr *E);
205 
206  /// \brief Generates a new transition in the program state graph
207  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
208  ///
209  /// @param State The state of the generated node. If not specified, the state
210  /// will not be changed, but the new node will have the checker's tag.
211  /// @param Tag The tag is used to uniquely identify the creation site. If no
212  /// tag is specified, a default tag, unique to the given checker,
213  /// will be used. Tags are used to prevent states generated at
214  /// different sites from caching out.
216  const ProgramPointTag *Tag = nullptr) {
217  return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
218  }
219 
220  /// \brief Generates a new transition with the given predecessor.
221  /// Allows checkers to generate a chain of nodes.
222  ///
223  /// @param State The state of the generated node.
224  /// @param Pred The transition will be generated from the specified Pred node
225  /// to the newly generated node.
226  /// @param Tag The tag to uniquely identify the creation site.
228  ExplodedNode *Pred,
229  const ProgramPointTag *Tag = nullptr) {
230  return addTransitionImpl(State, false, Pred, Tag);
231  }
232 
233  /// \brief Generate a sink node. Generating a sink stops exploration of the
234  /// given path. To create a sink node for the purpose of reporting an error,
235  /// checkers should use generateErrorNode() instead.
237  const ProgramPointTag *Tag = nullptr) {
238  return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
239  }
240 
241  /// \brief Generate a transition to a node that will be used to report
242  /// an error. This node will be a sink. That is, it will stop exploration of
243  /// the given path.
244  ///
245  /// @param State The state of the generated node.
246  /// @param Tag The tag to uniquely identify the creation site. If null,
247  /// the default tag for the checker will be used.
249  const ProgramPointTag *Tag = nullptr) {
250  return generateSink(State, Pred,
251  (Tag ? Tag : Location.getTag()));
252  }
253 
254  /// \brief Generate a transition to a node that will be used to report
255  /// an error. This node will not be a sink. That is, exploration will
256  /// continue along this path.
257  ///
258  /// @param State The state of the generated node.
259  /// @param Tag The tag to uniquely identify the creation site. If null,
260  /// the default tag for the checker will be used.
261  ExplodedNode *
263  const ProgramPointTag *Tag = nullptr) {
264  return addTransition(State, (Tag ? Tag : Location.getTag()));
265  }
266 
267  /// \brief Emit the diagnostics report.
268  void emitReport(std::unique_ptr<BugReport> R) {
269  Changed = true;
270  Eng.getBugReporter().emitReport(std::move(R));
271  }
272 
273  /// \brief Returns the word that should be used to refer to the declaration
274  /// in the report.
275  StringRef getDeclDescription(const Decl *D);
276 
277  /// \brief Get the declaration of the called function (path-sensitive).
278  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
279 
280  /// \brief Get the name of the called function (path-sensitive).
281  StringRef getCalleeName(const FunctionDecl *FunDecl) const;
282 
283  /// \brief Get the identifier of the called function (path-sensitive).
284  const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const {
285  const FunctionDecl *FunDecl = getCalleeDecl(CE);
286  if (FunDecl)
287  return FunDecl->getIdentifier();
288  else
289  return nullptr;
290  }
291 
292  /// \brief Get the name of the called function (path-sensitive).
293  StringRef getCalleeName(const CallExpr *CE) const {
294  const FunctionDecl *FunDecl = getCalleeDecl(CE);
295  return getCalleeName(FunDecl);
296  }
297 
298  /// \brief Returns true if the callee is an externally-visible function in the
299  /// top-level namespace, such as \c malloc.
300  ///
301  /// If a name is provided, the function must additionally match the given
302  /// name.
303  ///
304  /// Note that this deliberately excludes C++ library functions in the \c std
305  /// namespace, but will include C library functions accessed through the
306  /// \c std namespace. This also does not check if the function is declared
307  /// as 'extern "C"', or if it uses C++ name mangling.
308  static bool isCLibraryFunction(const FunctionDecl *FD,
309  StringRef Name = StringRef());
310 
311  /// \brief Depending on wither the location corresponds to a macro, return
312  /// either the macro name or the token spelling.
313  ///
314  /// This could be useful when checkers' logic depends on whether a function
315  /// is called with a given macro argument. For example:
316  /// s = socket(AF_INET,..)
317  /// If AF_INET is a macro, the result should be treated as a source of taint.
318  ///
319  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
321 
322 private:
323  ExplodedNode *addTransitionImpl(ProgramStateRef State,
324  bool MarkAsSink,
325  ExplodedNode *P = nullptr,
326  const ProgramPointTag *Tag = nullptr) {
327  // The analyzer may stop exploring if it sees a state it has previously
328  // visited ("cache out"). The early return here is a defensive check to
329  // prevent accidental caching out by checker API clients. Unless there is a
330  // tag or the client checker has requested that the generated node be
331  // marked as a sink, we assume that a client requesting a transition to a
332  // state that is the same as the predecessor state has made a mistake. We
333  // return the predecessor rather than cache out.
334  //
335  // TODO: We could potentially change the return to an assertion to alert
336  // clients to their mistake, but several checkers (including
337  // DereferenceChecker, CallAndMessageChecker, and DynamicTypePropagation)
338  // rely upon the defensive behavior and would need to be updated.
339  if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
340  return Pred;
341 
342  Changed = true;
343  const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
344  if (!P)
345  P = Pred;
346 
347  ExplodedNode *node;
348  if (MarkAsSink)
349  node = NB.generateSink(LocalLoc, State, P);
350  else
351  node = NB.generateNode(LocalLoc, State, P);
352  return node;
353  }
354 };
355 
356 } // end GR namespace
357 
358 } // end clang namespace
359 
360 #endif
An instance of this class is created to represent a function declaration or definition.
Definition: Decl.h:1697
StringRef getCalleeName(const CallExpr *CE) const
Get the name of the called function (path-sensitive).
SymbolManager & getSymbolManager()
Definition: SValBuilder.h:154
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:79
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:195
Stmt - This represents one statement.
Definition: Stmt.h:66
unsigned getBlockID() const
Definition: CFG.h:729
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:86
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:133
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
getIdentifier - Get the identifier that names this declaration, if there is one.
Definition: Decl.h:265
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:149
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:401
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
BugReporter & getBugReporter()
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:275
Expr - 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:211
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:123
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:403
#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:125
void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
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:63
BugReporter & getBugReporter()
Definition: ExprEngine.h:133
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:131
StoreManager & getStoreManager()
Definition: ExprEngine.h:307
const NodeBuilderContext & getContext()
Definition: CoreEngine.h:299
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:178
ProgramStateManager & getStateManager() override
Definition: ExprEngine.h:305
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:264
SourceManager & getSourceManager()
Definition: BugReporter.h:463
AnalysisDeclContext * getCurrentAnalysisDeclContext() const
SourceManager & getSourceManager()
SValBuilder & getSValBuilder()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2218
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:152
ConstraintManager & getConstraintManager()
Definition: ExprEngine.h:309
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:688
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:191
const LangOptions & getLangOpts() const