clang  6.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 getState()->getSVal(S, getLocationContext());
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
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1698
StringRef getCalleeName(const CallExpr *CE) const
Get the name of the called function (path-sensitive).
SymbolManager & getSymbolManager()
Definition: SValBuilder.h:147
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:132
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:400
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
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:177
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:2209
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:151
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