clang: include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
19#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
20
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
39#include
40#include
41#include
42#include
43#include
44
46
47class CFG;
49class Expr;
50class ParentMap;
51class Stmt;
52
53namespace ento {
54
55class ExplodedGraph;
56
57
58
59
60
61
62
63
64
65
74
75
76
77
78
79
80
81
82
83
84 class NodeGroup {
85
86
87
88
90
91 public:
92 NodeGroup(bool Flag = false) : P(Flag) {
93 assert(getFlag() == Flag);
94 }
95
97
99
100 unsigned size() const;
101
102 bool empty() const { return P == 0 || getFlag() != 0; }
103
104
105
106
108
109
110
111
112
113
114 void replaceNode(ExplodedNode *node);
115
116
117 bool getFlag() const {
118 return (P & 1);
119 }
120 };
121
122
123
124 const ProgramPoint Location;
125
126
128
129
130 NodeGroup Preds;
131
132
133 NodeGroup Succs;
134
136
137public:
139 int64_t Id, bool IsSink)
140 : Location(loc), State(std::move(state)), Succs(IsSink), Id(Id) {
141 assert(isSink() == IsSink);
142 }
143
144
146
149 }
150
153 }
154
156
158
160
163 }
164
167 }
168
170
171 template std::optional getLocationAs() const & {
172 return Location.getAs<T>();
173 }
174
175
178 }
179
180 static void Profile(llvm::FoldingSetNodeID &ID,
183 bool IsSink) {
185 ID.AddPointer(state.get());
186 ID.AddBoolean(IsSink);
187 }
188
189 void Profile(llvm::FoldingSetNodeID& ID) const {
190
192 }
193
194
195
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
207 }
208
211 }
212
215 }
216
219 }
220
223 }
224
225
227 using succ_range = llvm::iterator_range<succ_iterator>;
228
231
233 using pred_range = llvm::iterator_range<pred_iterator>;
234
237
241
244 }
247 }
249
253
256 }
259 }
261
263
264
265
266
267
268
270
271
272
273
274
276
277
278
279
280
282
283
284
285
286
288
289
290
291
292
294
295private:
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
304protected:
306
307
309
310
311
312
313
315
316
317
319
320
322
323
324
326
327
329
330
332
333
335
336
337
338
340
341
343
344public:
347
348
349
350
351
353 bool IsSink = false,
354 bool* IsNew = nullptr);
355
356
357
358
359
362 int64_t Id,
363 bool IsSink = false);
364
366 return std::make_unique();
367 }
368
369
372 return V;
373 }
374
375
378 return V;
379 }
380
383
386
387 void reserve(unsigned NodeCount) { Nodes.reserve(NodeCount); }
388
389
391 using AllNodesTy = llvm::FoldingSet;
398
399 llvm::iterator_range<node_iterator> nodes() { return Nodes; }
400
401 llvm::iterator_range<const_node_iterator> nodes() const { return Nodes; }
402
404
406
408
410
412
414
416
418
421
422 using NodeMap = llvm::DenseMap<const ExplodedNode *, ExplodedNode *>;
423
424
425
426
427
428
429
430
431
432
433
434 std::unique_ptr
438
439
440
443 }
444
445
446
448
449
450
452
453private:
454 bool shouldCollect(const ExplodedNode *node);
456};
457
461
462public:
464 assert(N && !static_cast<ExplodedNode*>(N)->isSink());
465 Impl.insert(N);
466 }
467
469
471 if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
472 }
473
476
477 unsigned size() const { return Impl.size(); }
478 bool empty() const { return Impl.empty(); }
480
481 void clear() { Impl.clear(); }
482
484 assert(&S != this);
486 Impl = S.Impl;
487 else
488 Impl.insert(S.begin(), S.end());
489 }
490
493
496};
497
498}
499
500}
501
502
503
504namespace llvm {
505 template <> struct GraphTraits<clang::ento::ExplodedGraph *> {
510
513 }
514
517 }
518
520 if (predecessorOfTrivial(N))
521 return child_begin(*N->succ_begin());
523 }
524
526 if (predecessorOfTrivial(N))
529 }
530
532 return df_begin(G);
533 }
534
536 return df_end(G);
537 }
538 };
539}
540
541#endif
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::BumpPtrAllocator & getAllocator()
Represents a single basic block in a source-level CFG.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
const ParentMap & getParentMap() const
const StackFrameContext * getStackFrame() const
const LocationContext * getLocationContext() const
It represents a stack frame of the call stack (based on CallEvent).
Stmt - This represents one statement.
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
CoreEngine - Implements the core logic of the graph-reachability analysis.
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
unsigned num_eops() const
ExplodedNode * addRoot(ExplodedNode *V)
addRoot - Add an untyped node to the set of roots.
roots_iterator roots_end()
BumpVectorContext & getNodeAllocator()
std::vector< ExplodedNode * > NodeVector
unsigned ReclaimCounter
Counter to determine when to reclaim 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.
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
llvm::iterator_range< const_node_iterator > nodes() 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
llvm::BumpPtrAllocator & getAllocator()
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
NodeVector::const_iterator const_eop_iterator
BumpVectorContext BVC
BVC - Allocator and context for allocating nodes and their predecessor and successor groups.
llvm::iterator_range< node_iterator > nodes()
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::DenseMap< const ExplodedNode *, ExplodedNode * > NodeMap
ExplodedNode * addEndOfPath(ExplodedNode *V)
addEndOfPath - Add an untyped node to the set of EOP nodes.
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::iterator iterator
ImplTy::const_iterator const_iterator
void insert(const ExplodedNodeSet &S)
const_iterator end() const
void Add(ExplodedNode *N)
ExplodedNodeSet()=default
const_iterator begin() const
const CFGBlock * getCFGBlock() const
llvm::iterator_range< pred_iterator > pred_range
const ProgramStateRef & getState() const
friend class ExplodedGraph
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
ExplodedNode * getFirstSucc()
unsigned pred_size() const
static void Profile(llvm::FoldingSetNodeID &ID, const ProgramPoint &Loc, const ProgramStateRef &state, bool IsSink)
const ExplodedNode * getFirstSucc() const
ExplodedNode(const ProgramPoint &loc, ProgramStateRef state, int64_t Id, bool IsSink)
bool hasSinglePred() const
const_succ_range succs() const
succ_iterator succ_begin()
const Stmt * getNextStmtForDiagnostics() const
Find the next statement that was executed on this node's execution path.
const StackFrameContext * getStackFrame() const
ExplodedNode *const * succ_iterator
const ExplodedNode * getFirstPred() const
const_pred_range preds() const
friend class EndOfFunctionNodeBuilder
const ParentMap & getParentMap() const
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
const LocationContext * getLocationContext() const
std::optional< T > getLocationAs() const &
const Stmt * getCurrentOrPreviousStmtForDiagnostics() const
Find the statement that was executed at or immediately before this node.
const ExplodedNode *const * const_pred_iterator
ExplodedNode * getFirstPred()
const_succ_iterator succ_end() const
unsigned succ_size() const
ExplodedNode *const * pred_iterator
const ExplodedNode *const * const_succ_iterator
const Decl & getCodeDecl() const
const_pred_iterator pred_end() const
This is the simplest builder which generates nodes in the ExplodedGraph.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
@ 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
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
__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 bool predecessorOfTrivial(NodeRef N)
static nodes_iterator nodes_begin(const GraphTy G)
static ChildIteratorType child_end(NodeRef N)
llvm::df_iterator< GraphTy > nodes_iterator
clang::ento::ExplodedNode::succ_iterator ChildIteratorType
static NodeRef getEntryNode(const GraphTy G)
static ChildIteratorType child_begin(NodeRef N)