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
53public:
55 std::vector<std::pair<BlockEntrance, const ExplodedNode *>>;
56
58 std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>;
59
60private:
61 ExprEngine &ExprEng;
62
63 /// G - The simulation graph. Each node is a (location,state) pair.
64 mutable ExplodedGraph G;
65
66 /// WList - A set of queued nodes that need to be processed by the
67 /// worklist algorithm. It is up to the implementation of WList to decide
68 /// the order that nodes are processed.
69 std::unique_ptr<WorkList> WList;
70 std::unique_ptr<WorkList> CTUWList;
71
72 /// BCounterFactory - A factory object for created BlockCounter objects.
73 /// These are used to record for key nodes in the ExplodedGraph the
74 /// number of times different CFGBlocks have been visited along a path.
75 BlockCounter::Factory BCounterFactory;
76
77 /// The locations where we stopped doing work because we visited a location
78 /// too many times.
79 BlocksExhausted blocksExhausted;
80
81 /// The locations where we stopped because the engine aborted analysis,
82 /// usually because it could not reason about something.
83 BlocksAborted blocksAborted;
84
85 /// Whether the single-TU phase completed the exploration of all paths
86 /// within its budget limit.
87 /// The CTU phase replaces \c WList, so this has to be remembered separately.
88 bool ExploredAllSTUPaths = false;
89
90 /// The information about functions shared by the whole translation unit.
91 /// (This data is owned by AnalysisConsumer.)
92 FunctionSummariesTy *FunctionSummaries;
93
94 /// Add path tags with some useful data along the path when we see that
95 /// something interesting is happening. This field is the allocator for such
96 /// tags.
97 DataTag::Factory DataTags;
98
99 void setBlockCounter(BlockCounter C);
100
101 void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
102 void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred);
103 void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred);
104
105 void HandleCallEnter(const CallEnter &CE, ExplodedNode *Pred);
106
107 void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred);
108
109 void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
110 ExplodedNode *Pred);
111 void HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
112 const CFGBlock *B, ExplodedNode *Pred);
113
114 /// Handle conditional logic for running static initializers.
115 void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
116 ExplodedNode *Pred);
117
118 void HandleVirtualBaseBranch(const CFGBlock *B, ExplodedNode *Pred);
119
120private:
121 /// Helper function called by `HandleBranch()`. If the currently handled
122 /// branch corresponds to a loop, this returns the number of already
123 /// completed iterations in that loop, otherwise the return value is
124 /// `std::nullopt`. Note that this counts _all_ earlier iterations, including
125 /// ones that were performed within an earlier iteration of an outer loop.
126 std::optional<unsigned> getCompletedIterationCount(const CFGBlock *B,
127 ExplodedNode *Pred) const;
128
129public:
130 /// Construct a CoreEngine object to analyze the provided CFG.
131 CoreEngine(ExprEngine &exprengine,
133 AnalyzerOptions &Opts);
134
135 CoreEngine(const CoreEngine &) = delete;
136 CoreEngine &operator=(const CoreEngine &) = delete;
137
138 /// getGraph - Returns the exploded graph.
139 ExplodedGraph &getGraph() { return G; }
140
141 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
142 /// steps. Returns true if there is still simulation state on the worklist.
143 bool ExecuteWorkList(const StackFrame *SF, unsigned Steps,
144 ProgramStateRef InitState);
145
146 /// Dispatch the work list item based on the given location information.
147 /// Use Pred parameter as the predecessor state.
149 const WorkListUnit& WU);
150
151 // Functions for external checking of whether we have unfinished work.
152 bool wasBlockAborted() const { return !blocksAborted.empty(); }
153 bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
154 bool hasExploredAllPaths() const {
155 return !wasBlocksExhausted() && !WList->hasWork() && ExploredAllSTUPaths &&
157 }
158
159 /// Inform the CoreEngine that a basic block was aborted because
160 /// it could not be completely analyzed.
161 void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
162 blocksAborted.push_back(std::make_pair(block, node));
163 }
164
165 WorkList *getWorkList() const { return WList.get(); }
166 WorkList *getCTUWorkList() const { return CTUWList.get(); }
167
168 auto exhausted_blocks() const {
169 return llvm::iterator_range(blocksExhausted);
170 }
171
172 auto aborted_blocks() const { return llvm::iterator_range(blocksAborted); }
173
175 ExplodedNode *Pred, bool MarkAsSink = false) const;
176
178 ExplodedNode *Pred,
179 bool MarkAsSink = false) const {
180 PostStmt Loc(S, Pred->getStackFrame(), /*tag=*/nullptr);
181 return makeNode(Loc, State, Pred, MarkAsSink);
182 }
183
186 ProgramStateRef State,
188 const StackFrame *SF = Pred->getStackFrame();
189 State = State->BindExpr(E, SF, V);
190 const auto &L = ProgramPoint::getProgramPoint(E, K, SF, /*tag=*/nullptr);
191 return makeNode(L, State, Pred);
192 }
193
197 return makeNodeWithBinding(Pred, E, V, Pred->getState(), K);
198 }
199
200 /// Enqueue the given set of nodes onto the work list.
202
203 /// Enqueue nodes that were created as a result of processing
204 /// a statement onto the work list.
206 unsigned Idx);
207
208 /// enqueue the nodes corresponding to the end of function onto the
209 /// end of path / work list.
211
212 /// Enqueue a single node created as a result of statement processing.
213 void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
214
215 DataTag::Factory &getDataTags() { return DataTags; }
216};
217
218} // namespace ento
219
220} // namespace clang
221
222#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:525
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...
bool hasExploredAllPaths() const
Definition CoreEngine.h:154
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:161
CoreEngine(ExprEngine &exprengine, FunctionSummariesTy *FS, AnalyzerOptions &Opts)
Construct a CoreEngine object to analyze the provided CFG.
DataTag::Factory & getDataTags()
Definition CoreEngine.h:215
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:152
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:57
WorkList * getCTUWorkList() const
Definition CoreEngine.h:166
bool wasBlocksExhausted() const
Definition CoreEngine.h:153
WorkList * getWorkList() const
Definition CoreEngine.h:165
std::vector< std::pair< BlockEntrance, const ExplodedNode * > > BlocksExhausted
Definition CoreEngine.h:54
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
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:177
auto exhausted_blocks() const
Definition CoreEngine.h:168
ExplodedGraph & getGraph()
getGraph - Returns the exploded graph.
Definition CoreEngine.h:139
ExplodedNode * makeNodeWithBinding(ExplodedNode *Pred, const Expr *E, SVal V, ProgramPoint::Kind K=ProgramPoint::PostStmtKind) const
Definition CoreEngine.h:195
ExplodedNode * makeNodeWithBinding(ExplodedNode *Pred, const Expr *E, SVal V, ProgramStateRef State, ProgramPoint::Kind K=ProgramPoint::PostStmtKind) const
Definition CoreEngine.h:185
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:172
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
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.