clang  19.0.0git
CoreEngine.h
Go to the documentation of this file.
1 //===- CoreEngine.h - Path-Sensitive Dataflow Engine ------------*- 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 a generic engine for intraprocedural, path-sensitive,
10 // dataflow analysis via graph reachability.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
16 
17 #include "clang/AST/Stmt.h"
19 #include "clang/Analysis/CFG.h"
21 #include "clang/Basic/LLVM.h"
27 #include "llvm/ADT/SmallVector.h"
28 #include "llvm/ADT/iterator_range.h"
29 #include "llvm/Support/Casting.h"
30 #include <cassert>
31 #include <memory>
32 #include <utility>
33 #include <vector>
34 
35 namespace clang {
36 
37 class AnalyzerOptions;
38 class CXXBindTemporaryExpr;
39 class Expr;
40 class LabelDecl;
41 
42 namespace ento {
43 
44 class FunctionSummariesTy;
45 class ExprEngine;
46 
47 //===----------------------------------------------------------------------===//
48 /// CoreEngine - Implements the core logic of the graph-reachability
49 /// analysis. It traverses the CFG and generates the ExplodedGraph.
50 /// Program "states" are treated as opaque void pointers.
51 /// The template class CoreEngine (which subclasses CoreEngine)
52 /// provides the matching component to the engine that knows the actual types
53 /// for states. Note that this engine only dispatches to transfer functions
54 /// at the statement and block-level. The analyses themselves must implement
55 /// any transfer function logic and the sub-expression level (if any).
56 class CoreEngine {
57  friend class CommonNodeBuilder;
59  friend class ExprEngine;
61  friend class NodeBuilder;
62  friend class NodeBuilderContext;
63  friend class SwitchNodeBuilder;
64 
65 public:
67  std::vector<std::pair<BlockEdge, const ExplodedNode *>>;
68 
69  using BlocksAborted =
70  std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>;
71 
72 private:
73  ExprEngine &ExprEng;
74 
75  /// G - The simulation graph. Each node is a (location,state) pair.
76  mutable ExplodedGraph G;
77 
78  /// WList - A set of queued nodes that need to be processed by the
79  /// worklist algorithm. It is up to the implementation of WList to decide
80  /// the order that nodes are processed.
81  std::unique_ptr<WorkList> WList;
82  std::unique_ptr<WorkList> CTUWList;
83 
84  /// BCounterFactory - A factory object for created BlockCounter objects.
85  /// These are used to record for key nodes in the ExplodedGraph the
86  /// number of times different CFGBlocks have been visited along a path.
87  BlockCounter::Factory BCounterFactory;
88 
89  /// The locations where we stopped doing work because we visited a location
90  /// too many times.
91  BlocksExhausted blocksExhausted;
92 
93  /// The locations where we stopped because the engine aborted analysis,
94  /// usually because it could not reason about something.
95  BlocksAborted blocksAborted;
96 
97  /// The information about functions shared by the whole translation unit.
98  /// (This data is owned by AnalysisConsumer.)
99  FunctionSummariesTy *FunctionSummaries;
100 
101  /// Add path tags with some useful data along the path when we see that
102  /// something interesting is happening. This field is the allocator for such
103  /// tags.
104  DataTag::Factory DataTags;
105 
106  void setBlockCounter(BlockCounter C);
107 
108  void generateNode(const ProgramPoint &Loc,
110  ExplodedNode *Pred);
111 
112  void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
113  void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred);
114  void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred);
115 
116  void HandleCallEnter(const CallEnter &CE, ExplodedNode *Pred);
117 
118  void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred);
119 
120  void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
121  ExplodedNode *Pred);
122  void HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
123  const CFGBlock *B, ExplodedNode *Pred);
124 
125  /// Handle conditional logic for running static initializers.
126  void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
127  ExplodedNode *Pred);
128 
129  void HandleVirtualBaseBranch(const CFGBlock *B, ExplodedNode *Pred);
130 
131 private:
132  ExplodedNode *generateCallExitBeginNode(ExplodedNode *N,
133  const ReturnStmt *RS);
134 
135 public:
136  /// Construct a CoreEngine object to analyze the provided CFG.
137  CoreEngine(ExprEngine &exprengine,
139  AnalyzerOptions &Opts);
140 
141  CoreEngine(const CoreEngine &) = delete;
142  CoreEngine &operator=(const CoreEngine &) = delete;
143 
144  /// getGraph - Returns the exploded graph.
145  ExplodedGraph &getGraph() { return G; }
146 
147  /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
148  /// steps. Returns true if there is still simulation state on the worklist.
149  bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
150  ProgramStateRef InitState);
151 
152  /// Dispatch the work list item based on the given location information.
153  /// Use Pred parameter as the predecessor state.
155  const WorkListUnit& WU);
156 
157  // Functions for external checking of whether we have unfinished work
158  bool wasBlockAborted() const { return !blocksAborted.empty(); }
159  bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
160  bool hasWorkRemaining() const { return wasBlocksExhausted() ||
161  WList->hasWork() ||
162  wasBlockAborted(); }
163 
164  /// Inform the CoreEngine that a basic block was aborted because
165  /// it could not be completely analyzed.
166  void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
167  blocksAborted.push_back(std::make_pair(block, node));
168  }
169 
170  WorkList *getWorkList() const { return WList.get(); }
171  WorkList *getCTUWorkList() const { return CTUWList.get(); }
172 
173  auto exhausted_blocks() const {
174  return llvm::iterator_range(blocksExhausted);
175  }
176 
177  auto aborted_blocks() const { return llvm::iterator_range(blocksAborted); }
178 
179  /// Enqueue the given set of nodes onto the work list.
180  void enqueue(ExplodedNodeSet &Set);
181 
182  /// Enqueue nodes that were created as a result of processing
183  /// a statement onto the work list.
184  void enqueue(ExplodedNodeSet &Set, const CFGBlock *Block, unsigned Idx);
185 
186  /// enqueue the nodes corresponding to the end of function onto the
187  /// end of path / work list.
188  void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS);
189 
190  /// Enqueue a single node created as a result of statement processing.
191  void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
192 
193  DataTag::Factory &getDataTags() { return DataTags; }
194 };
195 
197  const CoreEngine &Eng;
198  const CFGBlock *Block;
199  const LocationContext *LC;
200 
201 public:
203  const LocationContext *L)
204  : Eng(E), Block(B), LC(L) {
205  assert(B);
206  }
207 
209  : NodeBuilderContext(E, B, N->getLocationContext()) {}
210 
211  /// Return the CoreEngine associated with this builder.
212  const CoreEngine &getEngine() const { return Eng; }
213 
214  /// Return the CFGBlock associated with this builder.
215  const CFGBlock *getBlock() const { return Block; }
216 
217  /// Return the location context associated with this builder.
218  const LocationContext *getLocationContext() const { return LC; }
219 
220  /// Returns the number of times the current basic block has been
221  /// visited on the exploded graph path.
222  unsigned blockCount() const {
223  return Eng.WList->getBlockCounter().getNumVisited(
224  LC->getStackFrame(),
225  Block->getBlockID());
226  }
227 };
228 
229 /// \class NodeBuilder
230 /// This is the simplest builder which generates nodes in the
231 /// ExplodedGraph.
232 ///
233 /// The main benefit of the builder is that it automatically tracks the
234 /// frontier nodes (or destination set). This is the set of nodes which should
235 /// be propagated to the next step / builder. They are the nodes which have been
236 /// added to the builder (either as the input node set or as the newly
237 /// constructed nodes) but did not have any outgoing transitions added.
238 class NodeBuilder {
239  virtual void anchor();
240 
241 protected:
243 
244  /// Specifies if the builder results have been finalized. For example, if it
245  /// is set to false, autotransitions are yet to be generated.
246  bool Finalized;
247 
248  bool HasGeneratedNodes = false;
249 
250  /// The frontier set - a set of nodes which need to be propagated after
251  /// the builder dies.
253 
254  /// Checks if the results are ready.
255  virtual bool checkResults() {
256  return Finalized;
257  }
258 
260  for (const auto I : Frontier)
261  if (I->isSink())
262  return false;
263  return true;
264  }
265 
266  /// Allow subclasses to finalize results before result_begin() is executed.
267  virtual void finalizeResults() {}
268 
271  ExplodedNode *Pred,
272  bool MarkAsSink = false);
273 
274 public:
276  const NodeBuilderContext &Ctx, bool F = true)
277  : C(Ctx), Finalized(F), Frontier(DstSet) {
278  Frontier.Add(SrcNode);
279  }
280 
282  const NodeBuilderContext &Ctx, bool F = true)
283  : C(Ctx), Finalized(F), Frontier(DstSet) {
284  Frontier.insert(SrcSet);
285  assert(hasNoSinksInFrontier());
286  }
287 
288  virtual ~NodeBuilder() = default;
289 
290  /// Generates a node in the ExplodedGraph.
293  ExplodedNode *Pred) {
294  return generateNodeImpl(
295  PP, State, Pred,
296  /*MarkAsSink=*/State->isPosteriorlyOverconstrained());
297  }
298 
299  /// Generates a sink in the ExplodedGraph.
300  ///
301  /// When a node is marked as sink, the exploration from the node is stopped -
302  /// the node becomes the last node on the path and certain kinds of bugs are
303  /// suppressed.
306  ExplodedNode *Pred) {
307  return generateNodeImpl(PP, State, Pred, true);
308  }
309 
311  finalizeResults();
312  assert(checkResults());
313  return Frontier;
314  }
315 
317 
318  /// Iterators through the results frontier.
320  finalizeResults();
321  assert(checkResults());
322  return Frontier.begin();
323  }
324 
326  finalizeResults();
327  return Frontier.end();
328  }
329 
330  const NodeBuilderContext &getContext() { return C; }
332 
333  void takeNodes(const ExplodedNodeSet &S) {
334  for (const auto I : S)
335  Frontier.erase(I);
336  }
337 
339  void addNodes(const ExplodedNodeSet &S) { Frontier.insert(S); }
341 };
342 
343 /// \class NodeBuilderWithSinks
344 /// This node builder keeps track of the generated sink nodes.
346  void anchor() override;
347 
348 protected:
351 
352 public:
354  const NodeBuilderContext &Ctx, ProgramPoint &L)
355  : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
356 
358  ExplodedNode *Pred,
359  const ProgramPointTag *Tag = nullptr) {
360  const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
361  return NodeBuilder::generateNode(LocalLoc, State, Pred);
362  }
363 
365  const ProgramPointTag *Tag = nullptr) {
366  const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
367  ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred);
368  if (N && N->isSink())
369  sinksGenerated.push_back(N);
370  return N;
371  }
372 
374  return sinksGenerated;
375  }
376 };
377 
378 /// \class StmtNodeBuilder
379 /// This builder class is useful for generating nodes that resulted from
380 /// visiting a statement. The main difference from its parent NodeBuilder is
381 /// that it creates a statement specific ProgramPoint.
383  NodeBuilder *EnclosingBldr;
384 
385 public:
386  /// Constructs a StmtNodeBuilder. If the builder is going to process
387  /// nodes currently owned by another builder(with larger scope), use
388  /// Enclosing builder to transfer ownership.
390  const NodeBuilderContext &Ctx,
391  NodeBuilder *Enclosing = nullptr)
392  : NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
393  if (EnclosingBldr)
394  EnclosingBldr->takeNodes(SrcNode);
395  }
396 
398  const NodeBuilderContext &Ctx,
399  NodeBuilder *Enclosing = nullptr)
400  : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
401  if (EnclosingBldr)
402  for (const auto I : SrcSet)
403  EnclosingBldr->takeNodes(I);
404  }
405 
406  ~StmtNodeBuilder() override;
407 
410 
412  ExplodedNode *Pred,
413  ProgramStateRef St,
414  const ProgramPointTag *tag = nullptr,
417  Pred->getLocationContext(), tag);
418  return NodeBuilder::generateNode(L, St, Pred);
419  }
420 
422  ExplodedNode *Pred,
423  ProgramStateRef St,
424  const ProgramPointTag *tag = nullptr,
427  Pred->getLocationContext(), tag);
428  return NodeBuilder::generateSink(L, St, Pred);
429  }
430 };
431 
432 /// BranchNodeBuilder is responsible for constructing the nodes
433 /// corresponding to the two branches of the if statement - true and false.
435  const CFGBlock *DstT;
436  const CFGBlock *DstF;
437 
438  bool InFeasibleTrue;
439  bool InFeasibleFalse;
440 
441  void anchor() override;
442 
443 public:
445  const NodeBuilderContext &C,
446  const CFGBlock *dstT, const CFGBlock *dstF)
447  : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
448  InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
449  // The branch node builder does not generate autotransitions.
450  // If there are no successors it means that both branches are infeasible.
451  takeNodes(SrcNode);
452  }
453 
455  const NodeBuilderContext &C,
456  const CFGBlock *dstT, const CFGBlock *dstF)
457  : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
458  InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
459  takeNodes(SrcSet);
460  }
461 
463  ExplodedNode *Pred);
464 
465  const CFGBlock *getTargetBlock(bool branch) const {
466  return branch ? DstT : DstF;
467  }
468 
469  void markInfeasible(bool branch) {
470  if (branch)
471  InFeasibleTrue = true;
472  else
473  InFeasibleFalse = true;
474  }
475 
476  bool isFeasible(bool branch) {
477  return branch ? !InFeasibleTrue : !InFeasibleFalse;
478  }
479 };
480 
482  CoreEngine& Eng;
483  const CFGBlock *Src;
484  const CFGBlock &DispatchBlock;
485  const Expr *E;
486  ExplodedNode *Pred;
487 
488 public:
490  const Expr *e, const CFGBlock *dispatch, CoreEngine* eng)
491  : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
492 
493  class iterator {
495 
497 
499 
500  public:
501  // This isn't really a conventional iterator.
502  // We just implement the deref as a no-op for now to make range-based for
503  // loops work.
504  const iterator &operator*() const { return *this; }
505 
506  iterator &operator++() { ++I; return *this; }
507  bool operator!=(const iterator &X) const { return I != X.I; }
508 
509  const LabelDecl *getLabel() const {
510  return cast<LabelStmt>((*I)->getLabel())->getDecl();
511  }
512 
513  const CFGBlock *getBlock() const {
514  return *I;
515  }
516  };
517 
518  iterator begin() { return iterator(DispatchBlock.succ_begin()); }
519  iterator end() { return iterator(DispatchBlock.succ_end()); }
520 
521  ExplodedNode *generateNode(const iterator &I,
523  bool isSink = false);
524 
525  const Expr *getTarget() const { return E; }
526 
527  ProgramStateRef getState() const { return Pred->State; }
528 
530  return Pred->getLocationContext();
531  }
532 };
533 
535  CoreEngine& Eng;
536  const CFGBlock *Src;
537  const Expr *Condition;
538  ExplodedNode *Pred;
539 
540 public:
542  const Expr *condition, CoreEngine* eng)
543  : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
544 
545  class iterator {
546  friend class SwitchNodeBuilder;
547 
549 
551 
552  public:
553  iterator &operator++() { ++I; return *this; }
554  bool operator!=(const iterator &X) const { return I != X.I; }
555  bool operator==(const iterator &X) const { return I == X.I; }
556 
557  const CaseStmt *getCase() const {
558  return cast<CaseStmt>((*I)->getLabel());
559  }
560 
561  const CFGBlock *getBlock() const {
562  return *I;
563  }
564  };
565 
566  iterator begin() { return iterator(Src->succ_rbegin()+1); }
567  iterator end() { return iterator(Src->succ_rend()); }
568 
569  const SwitchStmt *getSwitch() const {
570  return cast<SwitchStmt>(Src->getTerminator());
571  }
572 
573  ExplodedNode *generateCaseStmtNode(const iterator &I,
575 
577  bool isSink = false);
578 
579  const Expr *getCondition() const { return Condition; }
580 
581  ProgramStateRef getState() const { return Pred->State; }
582 
584  return Pred->getLocationContext();
585  }
586 };
587 
588 } // namespace ento
589 
590 } // namespace clang
591 
592 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
const CFGBlock * Block
Definition: HTMLLogger.cpp:153
#define X(type, name)
Definition: Value.h:143
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
LineState State
Stores options for the analyzer from the command line.
Represents a single basic block in a source-level CFG.
Definition: CFG.h:604
succ_iterator succ_end()
Definition: CFG.h:985
succ_reverse_iterator succ_rend()
Definition: CFG.h:990
succ_reverse_iterator succ_rbegin()
Definition: CFG.h:989
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
Definition: CFG.h:962
CFGTerminator getTerminator() const
Definition: CFG.h:1079
succ_iterator succ_begin()
Definition: CFG.h:984
AdjacentBlocks::const_iterator const_succ_iterator
Definition: CFG.h:960
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1487
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:628
CaseStmt - Represent a case statement.
Definition: Stmt.h:1801
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1497
This represents one expression.
Definition: Expr.h:110
Represents the declaration of a label.
Definition: Decl.h:500
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const StackFrameContext * getStackFrame() const
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
Definition: ProgramPoint.h:38
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const LocationContext *LC, const ProgramPointTag *tag)
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:129
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3019
Stmt - This represents one statement.
Definition: Stmt.h:84
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2388
An abstract data type used to count the number of times a given block has been visited along a path a...
Definition: BlockCounter.h:29
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
Definition: CoreEngine.h:434
BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &C, const CFGBlock *dstT, const CFGBlock *dstF)
Definition: CoreEngine.h:444
void markInfeasible(bool branch)
Definition: CoreEngine.h:469
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
Definition: CoreEngine.cpp:651
bool isFeasible(bool branch)
Definition: CoreEngine.h:476
BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &C, const CFGBlock *dstT, const CFGBlock *dstF)
Definition: CoreEngine.h:454
const CFGBlock * getTargetBlock(bool branch) const
Definition: CoreEngine.h:465
CoreEngine - Implements the core logic of the graph-reachability analysis.
Definition: CoreEngine.h:56
void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block)
Inform the CoreEngine that a basic block was aborted because it could not be completely analyzed.
Definition: CoreEngine.h:166
CoreEngine(ExprEngine &exprengine, FunctionSummariesTy *FS, AnalyzerOptions &Opts)
Construct a CoreEngine object to analyze the provided CFG.
Definition: CoreEngine.cpp:75
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
Definition: CoreEngine.cpp:530
bool wasBlockAborted() const
Definition: CoreEngine.h:158
CoreEngine & operator=(const CoreEngine &)=delete
friend class CommonNodeBuilder
Definition: CoreEngine.h:57
void dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc, const WorkListUnit &WU)
Dispatch the work list item based on the given location information.
Definition: CoreEngine.cpp:182
bool wasBlocksExhausted() const
Definition: CoreEngine.h:159
ExplodedGraph & getGraph()
getGraph - Returns the exploded graph.
Definition: CoreEngine.h:145
WorkList * getCTUWorkList() const
Definition: CoreEngine.h:171
std::vector< std::pair< BlockEdge, const ExplodedNode * > > BlocksExhausted
Definition: CoreEngine.h:67
DataTag::Factory & getDataTags()
Definition: CoreEngine.h:193
WorkList * getWorkList() const
Definition: CoreEngine.h:170
CoreEngine(const CoreEngine &)=delete
std::vector< std::pair< const CFGBlock *, const ExplodedNode * > > BlocksAborted
Definition: CoreEngine.h:70
bool ExecuteWorkList(const LocationContext *L, unsigned Steps, ProgramStateRef InitState)
ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
Definition: CoreEngine.cpp:88
friend class EndOfFunctionNodeBuilder
Definition: CoreEngine.h:58
auto exhausted_blocks() const
Definition: CoreEngine.h:173
bool hasWorkRemaining() const
Definition: CoreEngine.h:160
void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS)
enqueue the nodes corresponding to the end of function onto the end of path / work list.
Definition: CoreEngine.cpp:605
auto aborted_blocks() const
Definition: CoreEngine.h:177
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
Definition: CoreEngine.cpp:594
bool erase(ExplodedNode *N)
void insert(const ExplodedNodeSet &S)
void Add(ExplodedNode *N)
const LocationContext * getLocationContext() const
bool operator!=(const iterator &X) const
Definition: CoreEngine.h:507
IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, const Expr *e, const CFGBlock *dispatch, CoreEngine *eng)
Definition: CoreEngine.h:489
ProgramStateRef getState() const
Definition: CoreEngine.h:527
const Expr * getTarget() const
Definition: CoreEngine.h:525
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
Definition: CoreEngine.cpp:665
const LocationContext * getLocationContext() const
Definition: CoreEngine.h:529
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, const LocationContext *L)
Definition: CoreEngine.h:202
const CoreEngine & getEngine() const
Return the CoreEngine associated with this builder.
Definition: CoreEngine.h:212
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
Definition: CoreEngine.h:208
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
Definition: CoreEngine.h:215
const LocationContext * getLocationContext() const
Return the location context associated with this builder.
Definition: CoreEngine.h:218
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
Definition: CoreEngine.h:222
This node builder keeps track of the generated sink nodes.
Definition: CoreEngine.h:345
NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, ProgramPoint &L)
Definition: CoreEngine.h:353
SmallVector< ExplodedNode *, 2 > sinksGenerated
Definition: CoreEngine.h:349
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Definition: CoreEngine.h:357
const SmallVectorImpl< ExplodedNode * > & getSinks() const
Definition: CoreEngine.h:373
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Definition: CoreEngine.h:364
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition: CoreEngine.h:238
const NodeBuilderContext & C
Definition: CoreEngine.h:242
virtual void finalizeResults()
Allow subclasses to finalize results before result_begin() is executed.
Definition: CoreEngine.h:267
bool Finalized
Specifies if the builder results have been finalized.
Definition: CoreEngine.h:246
virtual ~NodeBuilder()=default
void takeNodes(ExplodedNode *N)
Definition: CoreEngine.h:338
iterator begin()
Iterators through the results frontier.
Definition: CoreEngine.h:319
ExplodedNodeSet::iterator iterator
Definition: CoreEngine.h:316
void takeNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:333
NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, bool F=true)
Definition: CoreEngine.h:275
ExplodedNodeSet & Frontier
The frontier set - a set of nodes which need to be propagated after the builder dies.
Definition: CoreEngine.h:252
void addNodes(ExplodedNode *N)
Definition: CoreEngine.h:340
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Definition: CoreEngine.h:304
void addNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:339
NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, bool F=true)
Definition: CoreEngine.h:281
virtual bool checkResults()
Checks if the results are ready.
Definition: CoreEngine.h:255
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Definition: CoreEngine.h:291
ExplodedNode * generateNodeImpl(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Definition: CoreEngine.cpp:622
const ExplodedNodeSet & getResults()
Definition: CoreEngine.h:310
const NodeBuilderContext & getContext()
Definition: CoreEngine.h:330
This builder class is useful for generating nodes that resulted from visiting a statement.
Definition: CoreEngine.h:382
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:421
StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, NodeBuilder *Enclosing=nullptr)
Constructs a StmtNodeBuilder.
Definition: CoreEngine.h:389
StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, NodeBuilder *Enclosing=nullptr)
Definition: CoreEngine.h:397
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:411
bool operator==(const iterator &X) const
Definition: CoreEngine.h:555
bool operator!=(const iterator &X) const
Definition: CoreEngine.h:554
const CaseStmt * getCase() const
Definition: CoreEngine.h:557
const CFGBlock * getBlock() const
Definition: CoreEngine.h:561
const LocationContext * getLocationContext() const
Definition: CoreEngine.h:583
ProgramStateRef getState() const
Definition: CoreEngine.h:581
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
Definition: CoreEngine.cpp:699
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
Definition: CoreEngine.cpp:684
SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src, const Expr *condition, CoreEngine *eng)
Definition: CoreEngine.h:541
const SwitchStmt * getSwitch() const
Definition: CoreEngine.h:569
const Expr * getCondition() const
Definition: CoreEngine.h:579
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.