clang 24.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
35namespace clang {
36
37class AnalyzerOptions;
39class Expr;
40class LabelDecl;
41
42namespace ento {
43
45class ExprEngine;
46
47//===----------------------------------------------------------------------===//
48/// CoreEngine - Implements the core logic of the graph-reachability analysis.
49/// It traverses the CFG and generates the ExplodedGraph.
51 friend class ExprEngine;
52 friend class NodeBuilderContext;
53
54public:
56 std::vector<std::pair<BlockEntrance, const ExplodedNode *>>;
57
59 std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>;
60
61private:
62 ExprEngine &ExprEng;
63
64 /// G - The simulation graph. Each node is a (location,state) pair.
65 mutable ExplodedGraph G;
66
67 /// WList - A set of queued nodes that need to be processed by the
68 /// worklist algorithm. It is up to the implementation of WList to decide
69 /// the order that nodes are processed.
70 std::unique_ptr<WorkList> WList;
71 std::unique_ptr<WorkList> CTUWList;
72
73 /// BCounterFactory - A factory object for created BlockCounter objects.
74 /// These are used to record for key nodes in the ExplodedGraph the
75 /// number of times different CFGBlocks have been visited along a path.
76 BlockCounter::Factory BCounterFactory;
77
78 /// The locations where we stopped doing work because we visited a location
79 /// too many times.
80 BlocksExhausted blocksExhausted;
81
82 /// The locations where we stopped because the engine aborted analysis,
83 /// usually because it could not reason about something.
84 BlocksAborted blocksAborted;
85
86 /// The information about functions shared by the whole translation unit.
87 /// (This data is owned by AnalysisConsumer.)
88 FunctionSummariesTy *FunctionSummaries;
89
90 /// Add path tags with some useful data along the path when we see that
91 /// something interesting is happening. This field is the allocator for such
92 /// tags.
93 DataTag::Factory DataTags;
94
95 void setBlockCounter(BlockCounter C);
96
97 void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
98 void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred);
99 void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred);
100
101 void HandleCallEnter(const CallEnter &CE, ExplodedNode *Pred);
102
103 void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred);
104
105 void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
106 ExplodedNode *Pred);
107 void HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
108 const CFGBlock *B, ExplodedNode *Pred);
109
110 /// Handle conditional logic for running static initializers.
111 void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
112 ExplodedNode *Pred);
113
114 void HandleVirtualBaseBranch(const CFGBlock *B, ExplodedNode *Pred);
115
116private:
117 /// Helper function called by `HandleBranch()`. If the currently handled
118 /// branch corresponds to a loop, this returns the number of already
119 /// completed iterations in that loop, otherwise the return value is
120 /// `std::nullopt`. Note that this counts _all_ earlier iterations, including
121 /// ones that were performed within an earlier iteration of an outer loop.
122 std::optional<unsigned> getCompletedIterationCount(const CFGBlock *B,
123 ExplodedNode *Pred) const;
124
125public:
126 /// Construct a CoreEngine object to analyze the provided CFG.
127 CoreEngine(ExprEngine &exprengine,
129 AnalyzerOptions &Opts);
130
131 CoreEngine(const CoreEngine &) = delete;
132 CoreEngine &operator=(const CoreEngine &) = delete;
133
134 /// getGraph - Returns the exploded graph.
135 ExplodedGraph &getGraph() { return G; }
136
137 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
138 /// steps. Returns true if there is still simulation state on the worklist.
139 bool ExecuteWorkList(const StackFrame *SF, unsigned Steps,
140 ProgramStateRef InitState);
141
142 /// Dispatch the work list item based on the given location information.
143 /// Use Pred parameter as the predecessor state.
145 const WorkListUnit& WU);
146
147 // Functions for external checking of whether we have unfinished work.
148 bool wasBlockAborted() const { return !blocksAborted.empty(); }
149 bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
150 bool hasWorkRemaining() const { return wasBlocksExhausted() ||
151 WList->hasWork() ||
152 wasBlockAborted(); }
153
154 /// Inform the CoreEngine that a basic block was aborted because
155 /// it could not be completely analyzed.
156 void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
157 blocksAborted.push_back(std::make_pair(block, node));
158 }
159
160 WorkList *getWorkList() const { return WList.get(); }
161 WorkList *getCTUWorkList() const { return CTUWList.get(); }
162
163 auto exhausted_blocks() const {
164 return llvm::iterator_range(blocksExhausted);
165 }
166
167 auto aborted_blocks() const { return llvm::iterator_range(blocksAborted); }
168
170 ExplodedNode *Pred, bool MarkAsSink = false) const;
171
173 ExplodedNode *Pred,
174 bool MarkAsSink = false) const {
175 PostStmt Loc(S, Pred->getStackFrame(), /*tag=*/nullptr);
176 return makeNode(Loc, State, Pred, MarkAsSink);
177 }
178
181 ProgramStateRef State,
183 const StackFrame *SF = Pred->getStackFrame();
184 State = State->BindExpr(E, SF, V);
185 const auto &L = ProgramPoint::getProgramPoint(E, K, SF, /*tag=*/nullptr);
186 return makeNode(L, State, Pred);
187 }
188
192 return makeNodeWithBinding(Pred, E, V, Pred->getState(), K);
193 }
194
195 /// Enqueue the given set of nodes onto the work list.
197
198 /// Enqueue nodes that were created as a result of processing
199 /// a statement onto the work list.
201 unsigned Idx);
202
203 /// enqueue the nodes corresponding to the end of function onto the
204 /// end of path / work list.
206
207 /// Enqueue a single node created as a result of statement processing.
208 void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
209
210 DataTag::Factory &getDataTags() { return DataTags; }
211};
212
214 const CoreEngine &Eng;
215 const CFGBlock *Block;
216 const StackFrame *SF;
217
218public:
220 const StackFrame *S)
221 : Eng(E), Block(B), SF(S) {
222 assert(B);
223 }
224
227
228 /// Return the CoreEngine associated with this builder.
229 const CoreEngine &getEngine() const { return Eng; }
230
231 /// Return the CFGBlock associated with this builder.
232 const CFGBlock *getBlock() const { return Block; }
233
234 /// Return the stack frame associated with this builder.
235 const StackFrame *getStackFrame() const { return SF; }
236
237 /// Returns the number of times the current basic block has been
238 /// visited on the exploded graph path.
239 unsigned blockCount() const {
240 return Eng.WList->getBlockCounter().getNumVisited(SF, Block->getBlockID());
241 }
242};
243
244} // namespace ento
245
246} // namespace clang
247
248#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
#define V(N, I)
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.
Stores options for the analyzer from the command line.
Represents a single basic block in a source-level CFG.
Definition CFG.h:652
Represents binding an expression to a temporary.
Definition ExprCXX.h:1497
Represents a point when we begin processing an inlined call.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1643
This represents one expression.
Definition Expr.h:113
Represents the declaration of a label.
Definition Decl.h:524
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const StackFrame *SF, const ProgramPointTag *tag)
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3172
It represents a stack frame of the call stack.
Stmt - This represents one statement.
Definition Stmt.h:85
An abstract data type used to count the number of times a given block has been visited along a path a...
CoreEngine - Implements the core logic of the graph-reachability analysis.
Definition CoreEngine.h:50
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:156
CoreEngine(ExprEngine &exprengine, FunctionSummariesTy *FS, AnalyzerOptions &Opts)
Construct a CoreEngine object to analyze the provided CFG.
DataTag::Factory & getDataTags()
Definition CoreEngine.h:210
friend class ExprEngine
Definition CoreEngine.h:51
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
bool wasBlockAborted() const
Definition CoreEngine.h:148
CoreEngine & operator=(const CoreEngine &)=delete
void dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc, const WorkListUnit &WU)
Dispatch the work list item based on the given location information.
std::vector< std::pair< const CFGBlock *, const ExplodedNode * > > BlocksAborted
Definition CoreEngine.h:58
WorkList * getCTUWorkList() const
Definition CoreEngine.h:161
bool wasBlocksExhausted() const
Definition CoreEngine.h:149
WorkList * getWorkList() const
Definition CoreEngine.h:160
std::vector< std::pair< BlockEntrance, const ExplodedNode * > > BlocksExhausted
Definition CoreEngine.h:55
void enqueueStmtNodes(ExplodedNodeSet &Set, const CFGBlock *Block, unsigned Idx)
Enqueue nodes that were created as a result of processing a statement onto the work list.
CoreEngine(const CoreEngine &)=delete
friend class NodeBuilderContext
Definition CoreEngine.h:52
bool ExecuteWorkList(const StackFrame *SF, unsigned Steps, ProgramStateRef InitState)
ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
ExplodedNode * makePostStmtNode(const Stmt *S, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false) const
Definition CoreEngine.h:172
auto exhausted_blocks() const
Definition CoreEngine.h:163
bool hasWorkRemaining() const
Definition CoreEngine.h:150
ExplodedGraph & getGraph()
getGraph - Returns the exploded graph.
Definition CoreEngine.h:135
ExplodedNode * makeNodeWithBinding(ExplodedNode *Pred, const Expr *E, SVal V, ProgramPoint::Kind K=ProgramPoint::PostStmtKind) const
Definition CoreEngine.h:190
ExplodedNode * makeNodeWithBinding(ExplodedNode *Pred, const Expr *E, SVal V, ProgramStateRef State, ProgramPoint::Kind K=ProgramPoint::PostStmtKind) const
Definition CoreEngine.h:180
void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS)
enqueue the nodes corresponding to the end of function onto the end of path / work list.
auto aborted_blocks() const
Definition CoreEngine.h:167
ExplodedNode * makeNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false) const
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
const ProgramStateRef & getState() const
const StackFrame * getStackFrame() const
const CoreEngine & getEngine() const
Return the CoreEngine associated with this builder.
Definition CoreEngine.h:229
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
Definition CoreEngine.h:232
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
Definition CoreEngine.h:225
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, const StackFrame *S)
Definition CoreEngine.h:219
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
Definition CoreEngine.h:239
const StackFrame * getStackFrame() const
Return the stack frame associated with this builder.
Definition CoreEngine.h:235
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:57
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Top level wrappers for InstallAPI frontend operations.
Expr * Cond
};