clang  19.0.0git
ExplodedGraph.h
Go to the documentation of this file.
1 //===- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the template classes ExplodedNode and ExplodedGraph,
10 // which represent a path-sensitive, intra-procedural "exploded graph."
11 // See "Precise interprocedural dataflow analysis via graph reachability"
12 // by Reps, Horwitz, and Sagiv
13 // (http://portal.acm.org/citation.cfm?id=199462) for the definition of an
14 // exploded graph.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
19 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
20 
24 #include "clang/Basic/LLVM.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/DenseMap.h"
30 #include "llvm/ADT/DepthFirstIterator.h"
31 #include "llvm/ADT/FoldingSet.h"
32 #include "llvm/ADT/GraphTraits.h"
33 #include "llvm/ADT/STLExtras.h"
34 #include "llvm/ADT/SetVector.h"
35 #include "llvm/ADT/iterator_range.h"
36 #include "llvm/Support/Allocator.h"
37 #include "llvm/Support/Compiler.h"
38 #include <cassert>
39 #include <cstdint>
40 #include <memory>
41 #include <optional>
42 #include <utility>
43 #include <vector>
44 
45 namespace clang {
46 
47 class CFG;
48 class Decl;
49 class Expr;
50 class ParentMap;
51 class Stmt;
52 
53 namespace ento {
54 
55 class ExplodedGraph;
56 
57 //===----------------------------------------------------------------------===//
58 // ExplodedGraph "implementation" classes. These classes are not typed to
59 // contain a specific kind of state. Typed-specialized versions are defined
60 // on top of these classes.
61 //===----------------------------------------------------------------------===//
62 
63 // ExplodedNode is not constified all over the engine because we need to add
64 // successors to it at any time after creating it.
65 
66 class ExplodedNode : public llvm::FoldingSetNode {
67  friend class BranchNodeBuilder;
68  friend class CoreEngine;
70  friend class ExplodedGraph;
72  friend class NodeBuilder;
73  friend class SwitchNodeBuilder;
74 
75  /// Efficiently stores a list of ExplodedNodes, or an optional flag.
76  ///
77  /// NodeGroup provides opaque storage for a list of ExplodedNodes, optimizing
78  /// for the case when there is only one node in the group. This is a fairly
79  /// common case in an ExplodedGraph, where most nodes have only one
80  /// predecessor and many have only one successor. It can also be used to
81  /// store a flag rather than a node list, which ExplodedNode uses to mark
82  /// whether a node is a sink. If the flag is set, the group is implicitly
83  /// empty and no nodes may be added.
84  class NodeGroup {
85  // Conceptually a discriminated union. If the low bit is set, the node is
86  // a sink. If the low bit is not set, the pointer refers to the storage
87  // for the nodes in the group.
88  // This is not a PointerIntPair in order to keep the storage type opaque.
89  uintptr_t P;
90 
91  public:
92  NodeGroup(bool Flag = false) : P(Flag) {
93  assert(getFlag() == Flag);
94  }
95 
96  ExplodedNode * const *begin() const;
97 
98  ExplodedNode * const *end() const;
99 
100  unsigned size() const;
101 
102  bool empty() const { return P == 0 || getFlag() != 0; }
103 
104  /// Adds a node to the list.
105  ///
106  /// The group must not have been created with its flag set.
107  void addNode(ExplodedNode *N, ExplodedGraph &G);
108 
109  /// Replaces the single node in this group with a new node.
110  ///
111  /// Note that this should only be used when you know the group was not
112  /// created with its flag set, and that the group is empty or contains
113  /// only a single node.
114  void replaceNode(ExplodedNode *node);
115 
116  /// Returns whether this group was created with its flag set.
117  bool getFlag() const {
118  return (P & 1);
119  }
120  };
121 
122  /// Location - The program location (within a function body) associated
123  /// with this node.
124  const ProgramPoint Location;
125 
126  /// State - The state associated with this node.
127  ProgramStateRef State;
128 
129  /// Preds - The predecessors of this node.
130  NodeGroup Preds;
131 
132  /// Succs - The successors of this node.
133  NodeGroup Succs;
134 
135  int64_t Id;
136 
137 public:
138  explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
139  int64_t Id, bool IsSink)
140  : Location(loc), State(std::move(state)), Succs(IsSink), Id(Id) {
141  assert(isSink() == IsSink);
142  }
143 
144  /// getLocation - Returns the edge associated with the given node.
145  ProgramPoint getLocation() const { return Location; }
146 
148  return getLocation().getLocationContext();
149  }
150 
152  return getLocation().getStackFrame();
153  }
154 
155  const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
156 
157  CFG &getCFG() const { return *getLocationContext()->getCFG(); }
158 
159  const CFGBlock *getCFGBlock() const;
160 
161  const ParentMap &getParentMap() const {
162  return getLocationContext()->getParentMap();
163  }
164 
165  template <typename T> T &getAnalysis() const {
166  return *getLocationContext()->getAnalysis<T>();
167  }
168 
169  const ProgramStateRef &getState() const { return State; }
170 
171  template <typename T> std::optional<T> getLocationAs() const & {
172  return Location.getAs<T>();
173  }
174 
175  /// Get the value of an arbitrary expression at this node.
176  SVal getSVal(const Stmt *S) const {
177  return getState()->getSVal(S, getLocationContext());
178  }
179 
180  static void Profile(llvm::FoldingSetNodeID &ID,
181  const ProgramPoint &Loc,
182  const ProgramStateRef &state,
183  bool IsSink) {
184  ID.Add(Loc);
185  ID.AddPointer(state.get());
186  ID.AddBoolean(IsSink);
187  }
188 
189  void Profile(llvm::FoldingSetNodeID& ID) const {
190  // We avoid copy constructors by not using accessors.
191  Profile(ID, Location, State, isSink());
192  }
193 
194  /// addPredeccessor - Adds a predecessor to the current node, and
195  /// in tandem add this node as a successor of the other node.
197 
198  unsigned succ_size() const { return Succs.size(); }
199  unsigned pred_size() const { return Preds.size(); }
200  bool succ_empty() const { return Succs.empty(); }
201  bool pred_empty() const { return Preds.empty(); }
202 
203  bool isSink() const { return Succs.getFlag(); }
204 
205  bool hasSinglePred() const {
206  return (pred_size() == 1);
207  }
208 
210  return pred_empty() ? nullptr : *(pred_begin());
211  }
212 
213  const ExplodedNode *getFirstPred() const {
214  return const_cast<ExplodedNode*>(this)->getFirstPred();
215  }
216 
218  return succ_empty() ? nullptr : *(succ_begin());
219  }
220 
221  const ExplodedNode *getFirstSucc() const {
222  return const_cast<ExplodedNode*>(this)->getFirstSucc();
223  }
224 
225  // Iterators over successor and predecessor vertices.
226  using succ_iterator = ExplodedNode * const *;
227  using succ_range = llvm::iterator_range<succ_iterator>;
228 
229  using const_succ_iterator = const ExplodedNode * const *;
230  using const_succ_range = llvm::iterator_range<const_succ_iterator>;
231 
232  using pred_iterator = ExplodedNode * const *;
233  using pred_range = llvm::iterator_range<pred_iterator>;
234 
235  using const_pred_iterator = const ExplodedNode * const *;
236  using const_pred_range = llvm::iterator_range<const_pred_iterator>;
237 
238  pred_iterator pred_begin() { return Preds.begin(); }
239  pred_iterator pred_end() { return Preds.end(); }
240  pred_range preds() { return {Preds.begin(), Preds.end()}; }
241 
243  return const_cast<ExplodedNode*>(this)->pred_begin();
244  }
246  return const_cast<ExplodedNode*>(this)->pred_end();
247  }
248  const_pred_range preds() const { return {Preds.begin(), Preds.end()}; }
249 
250  succ_iterator succ_begin() { return Succs.begin(); }
251  succ_iterator succ_end() { return Succs.end(); }
252  succ_range succs() { return {Succs.begin(), Succs.end()}; }
253 
255  return const_cast<ExplodedNode*>(this)->succ_begin();
256  }
258  return const_cast<ExplodedNode*>(this)->succ_end();
259  }
260  const_succ_range succs() const { return {Succs.begin(), Succs.end()}; }
261 
262  int64_t getID() const { return Id; }
263 
264  /// The node is trivial if it has only one successor, only one predecessor,
265  /// it's predecessor has only one successor,
266  /// and its program state is the same as the program state of the previous
267  /// node.
268  /// Trivial nodes may be skipped while printing exploded graph.
269  bool isTrivial() const;
270 
271  /// If the node's program point corresponds to a statement, retrieve that
272  /// statement. Useful for figuring out where to put a warning or a note.
273  /// If the statement belongs to a body-farmed definition,
274  /// retrieve the call site for that definition.
275  const Stmt *getStmtForDiagnostics() const;
276 
277  /// Find the next statement that was executed on this node's execution path.
278  /// Useful for explaining control flow that follows the current node.
279  /// If the statement belongs to a body-farmed definition, retrieve the
280  /// call site for that definition.
281  const Stmt *getNextStmtForDiagnostics() const;
282 
283  /// Find the statement that was executed immediately before this node.
284  /// Useful when the node corresponds to a CFG block entrance.
285  /// If the statement belongs to a body-farmed definition, retrieve the
286  /// call site for that definition.
287  const Stmt *getPreviousStmtForDiagnostics() const;
288 
289  /// Find the statement that was executed at or immediately before this node.
290  /// Useful when any nearby statement will do.
291  /// If the statement belongs to a body-farmed definition, retrieve the
292  /// call site for that definition.
294 
295 private:
296  void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); }
297  void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); }
298 };
299 
301  llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>;
302 
304 protected:
305  friend class CoreEngine;
306 
307  // Type definitions.
308  using NodeVector = std::vector<ExplodedNode *>;
309 
310  /// The roots of the simulation graph. Usually there will be only
311  /// one, but clients are free to establish multiple subgraphs within a single
312  /// SimulGraph. Moreover, these subgraphs can often merge when paths from
313  /// different roots reach the same state at the same program location.
315 
316  /// The nodes in the simulation graph which have been
317  /// specially marked as the endpoint of an abstract simulation path.
319 
320  /// Nodes - The nodes in the graph.
321  llvm::FoldingSet<ExplodedNode> Nodes;
322 
323  /// BVC - Allocator and context for allocating nodes and their predecessor
324  /// and successor groups.
326 
327  /// NumNodes - The number of nodes in the graph.
329 
330  /// A list of recently allocated nodes that can potentially be recycled.
332 
333  /// A list of nodes that can be reused.
335 
336  /// Determines how often nodes are reclaimed.
337  ///
338  /// If this is 0, nodes will never be reclaimed.
339  unsigned ReclaimNodeInterval = 0;
340 
341  /// Counter to determine when to reclaim nodes.
342  unsigned ReclaimCounter;
343 
344 public:
347 
348  /// Retrieve the node associated with a (Location,State) pair,
349  /// where the 'Location' is a ProgramPoint in the CFG. If no node for
350  /// this pair exists, it is created. IsNew is set to true if
351  /// the node was freshly created.
353  bool IsSink = false,
354  bool* IsNew = nullptr);
355 
356  /// Create a node for a (Location, State) pair,
357  /// but don't store it for deduplication later. This
358  /// is useful when copying an already completed
359  /// ExplodedGraph for further processing.
362  int64_t Id,
363  bool IsSink = false);
364 
365  std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const {
366  return std::make_unique<ExplodedGraph>();
367  }
368 
369  /// addRoot - Add an untyped node to the set of roots.
371  Roots.push_back(V);
372  return V;
373  }
374 
375  /// addEndOfPath - Add an untyped node to the set of EOP nodes.
377  EndNodes.push_back(V);
378  return V;
379  }
380 
381  unsigned num_roots() const { return Roots.size(); }
382  unsigned num_eops() const { return EndNodes.size(); }
383 
384  bool empty() const { return NumNodes == 0; }
385  unsigned size() const { return NumNodes; }
386 
387  void reserve(unsigned NodeCount) { Nodes.reserve(NodeCount); }
388 
389  // Iterators.
391  using AllNodesTy = llvm::FoldingSet<ExplodedNode>;
392  using roots_iterator = NodeVector::iterator;
393  using const_roots_iterator = NodeVector::const_iterator;
394  using eop_iterator = NodeVector::iterator;
395  using const_eop_iterator = NodeVector::const_iterator;
396  using node_iterator = AllNodesTy::iterator;
397  using const_node_iterator = AllNodesTy::const_iterator;
398 
399  llvm::iterator_range<node_iterator> nodes() { return Nodes; }
400 
401  llvm::iterator_range<const_node_iterator> nodes() const { return Nodes; }
402 
403  roots_iterator roots_begin() { return Roots.begin(); }
404 
405  roots_iterator roots_end() { return Roots.end(); }
406 
407  const_roots_iterator roots_begin() const { return Roots.begin(); }
408 
409  const_roots_iterator roots_end() const { return Roots.end(); }
410 
411  eop_iterator eop_begin() { return EndNodes.begin(); }
412 
413  eop_iterator eop_end() { return EndNodes.end(); }
414 
415  const_eop_iterator eop_begin() const { return EndNodes.begin(); }
416 
417  const_eop_iterator eop_end() const { return EndNodes.end(); }
418 
419  llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
421 
422  using NodeMap = llvm::DenseMap<const ExplodedNode *, ExplodedNode *>;
423 
424  /// Creates a trimmed version of the graph that only contains paths leading
425  /// to the given nodes.
426  ///
427  /// \param Nodes The nodes which must appear in the final graph. Presumably
428  /// these are end-of-path nodes (i.e. they have no successors).
429  /// \param[out] ForwardMap A optional map from nodes in this graph to nodes in
430  /// the returned graph.
431  /// \param[out] InverseMap An optional map from nodes in the returned graph to
432  /// nodes in this graph.
433  /// \returns The trimmed graph
434  std::unique_ptr<ExplodedGraph>
436  InterExplodedGraphMap *ForwardMap = nullptr,
437  InterExplodedGraphMap *InverseMap = nullptr) const;
438 
439  /// Enable tracking of recently allocated nodes for potential reclamation
440  /// when calling reclaimRecentlyAllocatedNodes().
441  void enableNodeReclamation(unsigned Interval) {
442  ReclaimCounter = ReclaimNodeInterval = Interval;
443  }
444 
445  /// Reclaim "uninteresting" nodes created since the last time this method
446  /// was called.
448 
449  /// Returns true if nodes for the given expression kind are always
450  /// kept around.
451  static bool isInterestingLValueExpr(const Expr *Ex);
452 
453 private:
454  bool shouldCollect(const ExplodedNode *node);
455  void collectNode(ExplodedNode *node);
456 };
457 
460  ImplTy Impl;
461 
462 public:
464  assert(N && !static_cast<ExplodedNode*>(N)->isSink());
465  Impl.insert(N);
466  }
467 
468  ExplodedNodeSet() = default;
469 
470  void Add(ExplodedNode *N) {
471  if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
472  }
473 
474  using iterator = ImplTy::iterator;
475  using const_iterator = ImplTy::const_iterator;
476 
477  unsigned size() const { return Impl.size(); }
478  bool empty() const { return Impl.empty(); }
479  bool erase(ExplodedNode *N) { return Impl.remove(N); }
480 
481  void clear() { Impl.clear(); }
482 
483  void insert(const ExplodedNodeSet &S) {
484  assert(&S != this);
485  if (empty())
486  Impl = S.Impl;
487  else
488  Impl.insert(S.begin(), S.end());
489  }
490 
491  iterator begin() { return Impl.begin(); }
492  iterator end() { return Impl.end(); }
493 
494  const_iterator begin() const { return Impl.begin(); }
495  const_iterator end() const { return Impl.end(); }
496 };
497 
498 } // namespace ento
499 
500 } // namespace clang
501 
502 // GraphTraits
503 
504 namespace llvm {
505  template <> struct GraphTraits<clang::ento::ExplodedGraph *> {
509  using nodes_iterator = llvm::df_iterator<GraphTy>;
510 
511  static NodeRef getEntryNode(const GraphTy G) {
512  return *G->roots_begin();
513  }
514 
515  static bool predecessorOfTrivial(NodeRef N) {
516  return N->succ_size() == 1 && N->getFirstSucc()->isTrivial();
517  }
518 
520  if (predecessorOfTrivial(N))
521  return child_begin(*N->succ_begin());
522  return N->succ_begin();
523  }
524 
526  if (predecessorOfTrivial(N))
527  return child_end(N->getFirstSucc());
528  return N->succ_end();
529  }
530 
532  return df_begin(G);
533  }
534 
535  static nodes_iterator nodes_end(const GraphTy G) {
536  return df_end(G);
537  }
538  };
539 } // namespace llvm
540 
541 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
#define V(N, I)
Definition: ASTContext.h:3299
int Id
Definition: ASTDiff.cpp:190
StringRef P
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static char ID
Definition: Arena.cpp:183
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
LineState State
llvm::BumpPtrAllocator & getAllocator()
Definition: BumpVector.h:64
Represents a single basic block in a source-level CFG.
Definition: CFG.h:604
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1214
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
This represents one expression.
Definition: Expr.h:110
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
const ParentMap & getParentMap() const
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:175
const StackFrameContext * getStackFrame() const
Definition: ProgramPoint.h:179
It represents a stack frame of the call stack (based on CallEvent).
Stmt - This represents one statement.
Definition: Stmt.h:84
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
Definition: CoreEngine.h:434
CoreEngine - Implements the core logic of the graph-reachability analysis.
Definition: CoreEngine.h:56
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy * > Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
Creates a trimmed version of the graph that only contains paths leading to the given nodes.
const_roots_iterator roots_begin() const
ExplodedNode * addEndOfPath(ExplodedNode *V)
addEndOfPath - Add an untyped node to the set of EOP nodes.
unsigned num_eops() const
roots_iterator roots_end()
std::vector< ExplodedNode * > NodeVector
unsigned ReclaimCounter
Counter to determine when to reclaim nodes.
llvm::iterator_range< node_iterator > nodes()
void reserve(unsigned NodeCount)
NodeVector ChangedNodes
A list of recently allocated nodes that can potentially be recycled.
int64_t NumNodes
NumNodes - The number of nodes in the graph.
NodeVector Roots
The roots of the simulation graph.
BumpVectorContext & getNodeAllocator()
llvm::iterator_range< const_node_iterator > nodes() const
void enableNodeReclamation(unsigned Interval)
Enable tracking of recently allocated nodes for potential reclamation when calling reclaimRecentlyAll...
NodeVector::const_iterator const_roots_iterator
unsigned ReclaimNodeInterval
Determines how often nodes are reclaimed.
NodeVector EndNodes
The nodes in the simulation graph which have been specially marked as the endpoint of an abstract sim...
NodeVector::iterator eop_iterator
const_roots_iterator roots_end() const
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called.
static bool isInterestingLValueExpr(const Expr *Ex)
Returns true if nodes for the given expression kind are always kept around.
AllNodesTy::const_iterator const_node_iterator
unsigned num_roots() const
std::unique_ptr< ExplodedGraph > MakeEmptyGraph() const
AllNodesTy::iterator node_iterator
llvm::FoldingSet< ExplodedNode > AllNodesTy
ExplodedNode * getNode(const ProgramPoint &L, ProgramStateRef State, bool IsSink=false, bool *IsNew=nullptr)
Retrieve the node associated with a (Location,State) pair, where the 'Location' is a ProgramPoint in ...
const_eop_iterator eop_begin() const
ExplodedNode * addRoot(ExplodedNode *V)
addRoot - Add an untyped node to the set of roots.
NodeVector::const_iterator const_eop_iterator
BumpVectorContext BVC
BVC - Allocator and context for allocating nodes and their predecessor and successor groups.
roots_iterator roots_begin()
ExplodedNode * createUncachedNode(const ProgramPoint &L, ProgramStateRef State, int64_t Id, bool IsSink=false)
Create a node for a (Location, State) pair, but don't store it for deduplication later.
llvm::FoldingSet< ExplodedNode > Nodes
Nodes - The nodes in the graph.
llvm::BumpPtrAllocator & getAllocator()
llvm::DenseMap< const ExplodedNode *, ExplodedNode * > NodeMap
NodeVector::iterator roots_iterator
NodeVector FreeNodes
A list of nodes that can be reused.
const_eop_iterator eop_end() const
bool erase(ExplodedNode *N)
ExplodedNodeSet(ExplodedNode *N)
ImplTy::const_iterator const_iterator
void insert(const ExplodedNodeSet &S)
const_iterator end() const
void Add(ExplodedNode *N)
const_iterator begin() const
ExplodedNode * getFirstPred()
const CFGBlock * getCFGBlock() const
ExplodedNode * getFirstSucc()
llvm::iterator_range< pred_iterator > pred_range
const ProgramStateRef & getState() const
const ParentMap & getParentMap() const
const LocationContext * getLocationContext() const
pred_iterator pred_end()
llvm::iterator_range< const_succ_iterator > const_succ_range
pred_iterator pred_begin()
const_pred_iterator pred_begin() const
const Stmt * getStmtForDiagnostics() const
If the node's program point corresponds to a statement, retrieve that statement.
const_succ_iterator succ_begin() const
llvm::iterator_range< succ_iterator > succ_range
bool isTrivial() const
The node is trivial if it has only one successor, only one predecessor, it's predecessor has only one...
const Stmt * getPreviousStmtForDiagnostics() const
Find the statement that was executed immediately before this node.
void Profile(llvm::FoldingSetNodeID &ID) const
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
llvm::iterator_range< const_pred_iterator > const_pred_range
const StackFrameContext * getStackFrame() const
succ_iterator succ_end()
unsigned pred_size() const
static void Profile(llvm::FoldingSetNodeID &ID, const ProgramPoint &Loc, const ProgramStateRef &state, bool IsSink)
ExplodedNode(const ProgramPoint &loc, ProgramStateRef state, int64_t Id, bool IsSink)
const_succ_range succs() const
const Decl & getCodeDecl() const
succ_iterator succ_begin()
const ExplodedNode * getFirstPred() const
const Stmt * getNextStmtForDiagnostics() const
Find the next statement that was executed on this node's execution path.
const ExplodedNode * getFirstSucc() const
ExplodedNode *const * succ_iterator
const_pred_range preds() const
friend class EndOfFunctionNodeBuilder
Definition: ExplodedGraph.h:69
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
const Stmt * getCurrentOrPreviousStmtForDiagnostics() const
Find the statement that was executed at or immediately before this node.
const ExplodedNode *const * const_pred_iterator
const_succ_iterator succ_end() const
unsigned succ_size() const
std::optional< T > getLocationAs() const &
ExplodedNode *const * pred_iterator
const ExplodedNode *const * const_succ_iterator
const_pred_iterator pred_end() const
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition: CoreEngine.h:238
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:55
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::DenseMap< const ExplodedNode *, const ExplodedNode * > InterExplodedGraphMap
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
RangeSelector node(std::string ID)
Selects a node, including trailing semicolon, if any (for declarations and non-expression statements)...
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
long int64_t
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
Definition: Format.h:5433
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
static nodes_iterator nodes_end(const GraphTy G)
static nodes_iterator nodes_begin(const GraphTy G)
static ChildIteratorType child_end(NodeRef N)
clang::ento::ExplodedNode::succ_iterator ChildIteratorType
static NodeRef getEntryNode(const GraphTy G)
static ChildIteratorType child_begin(NodeRef N)