14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H 15 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H 27 #include "llvm/ADT/SmallVector.h" 28 #include "llvm/Support/Casting.h" 36 class AnalyzerOptions;
37 class CXXBindTemporaryExpr;
43 class FunctionSummariesTy;
66 std::vector<std::pair<BlockEdge, const ExplodedNode *>>;
69 std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>;
80 std::unique_ptr<WorkList> WList;
168 blocksAborted.push_back(std::make_pair(block, node));
174 return blocksExhausted.begin();
178 return blocksExhausted.end();
182 return blocksAborted.begin();
186 return blocksAborted.end();
213 : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
221 return Eng.WList->getBlockCounter().getNumVisited(
237 virtual void anchor();
246 bool HasGeneratedNodes =
false;
258 for (
const auto I : Frontier)
270 bool MarkAsSink =
false);
275 : C(Ctx), Finalized(F), Frontier(DstSet) {
276 Frontier.
Add(SrcNode);
281 : C(Ctx), Finalized(F), Frontier(DstSet) {
283 assert(hasNoSinksInFrontier());
292 return generateNodeImpl(PP, State, Pred,
false);
303 return generateNodeImpl(PP, State, Pred,
true);
308 assert(checkResults());
317 assert(checkResults());
318 return Frontier.
begin();
323 return Frontier.
end();
330 for (
const auto I : S)
342 void anchor()
override;
365 sinksGenerated.push_back(N);
370 return sinksGenerated;
388 :
NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
396 :
NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
398 for (
const auto I : SrcSet)
435 bool InFeasibleFalse;
437 void anchor()
override;
443 :
NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
444 InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
453 :
NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
454 InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
462 return branch ? DstT : DstF;
467 InFeasibleTrue =
true;
469 InFeasibleFalse =
true;
473 return branch ? !InFeasibleTrue : !InFeasibleFalse;
487 : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
501 return cast<LabelStmt>((*I)->getLabel())->getDecl();
514 bool isSink =
false);
528 const Expr *Condition;
534 : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
549 return cast<CaseStmt>((*I)->getLabel());
568 bool isSink =
false);
583 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H bool operator!=(const iterator &X) const
succ_reverse_iterator succ_rbegin()
const LabelDecl * getLabel() const
void markInfeasible(bool branch)
succ_iterator succ_begin()
ImplTy::iterator iterator
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
bool ExecuteWorkList(const LocationContext *L, unsigned Steps, ProgramStateRef InitState)
ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
Stmt - This represents one statement.
ExplodedNodeSet::iterator iterator
This builder class is useful for generating nodes that resulted from visiting a statement.
bool wasBlockAborted() const
unsigned getBlockID() const
Represents a point when we begin processing an inlined call.
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, const Expr *e, const CFGBlock *dispatch, CoreEngine *eng)
NoteTag::Factory & getNoteTags()
const CaseStmt * getCase() const
NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, ProgramPoint &L)
BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &C, const CFGBlock *dstT, const CFGBlock *dstF)
void takeNodes(const ExplodedNodeSet &S)
virtual void finalizeResults()
Allow subclasses to finalize results before result_begin() is executed.
BlocksAborted::const_iterator blocks_aborted_begin() const
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, ProgramStateRef InitState, ExplodedNodeSet &Dst)
Returns true if there is still simulation state on the worklist.
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const LocationContext *LC, const ProgramPointTag *tag)
BlocksExhausted::const_iterator blocks_exhausted_end() const
const CFGBlock * getTargetBlock(bool branch) const
bool hasWorkRemaining() const
bool operator==(const iterator &X) const
bool Finalized
Specifies if the builder results have been finalized.
CoreEngine(SubEngine &subengine, FunctionSummariesTy *FS, AnalyzerOptions &Opts)
Construct a CoreEngine object to analyze the provided CFG.
BlocksExhausted::const_iterator blocks_exhausted_begin() const
friend class CommonNodeBuilder
AdjacentBlocks::const_iterator const_succ_iterator
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
WorkList * getWorkList() const
void addNodes(ExplodedNode *N)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const LocationContext * getLocationContext() const
const CFGBlock * getBlock() const
ExplodedNodeSet & Frontier
The frontier set - a set of nodes which need to be propagated after the builder dies.
const SmallVectorImpl< ExplodedNode * > & getSinks() const
CaseStmt - Represent a case statement.
Represents binding an expression to a temporary.
StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, NodeBuilder *Enclosing=nullptr)
Represents a single basic block in a source-level CFG.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
This represents one expression.
ExplodedGraph & getGraph()
getGraph - Returns the exploded graph.
const Expr * getCondition() const
std::vector< std::pair< const CFGBlock *, const ExplodedNode * > > BlocksAborted
This is the simplest builder which generates nodes in the ExplodedGraph.
void Add(ExplodedNode *N)
const ExplodedNodeSet & getResults()
const LocationContext * getLocationContext() const
SmallVector< ExplodedNode *, 2 > sinksGenerated
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
bool hasNoSinksInFrontier()
const SwitchStmt * getSwitch() const
virtual bool checkResults()
Checks if the results are ready.
BlocksAborted::const_iterator blocks_aborted_end() const
const LocationContext * getLocationContext() const
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
bool wasBlocksExhausted() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Represents the declaration of a label.
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
void dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc, const WorkListUnit &WU)
Dispatch the work list item based on the given location information.
succ_reverse_iterator succ_rend()
bool operator!=(const iterator &X) const
void insert(const ExplodedNodeSet &S)
std::vector< std::pair< BlockEdge, const ExplodedNode * > > BlocksExhausted
CoreEngine - Implements the core logic of the graph-reachability analysis.
Dataflow Directional Tag Classes.
void takeNodes(ExplodedNode *N)
void addNodes(const ExplodedNodeSet &S)
const NodeBuilderContext & getContext()
BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &C, const CFGBlock *dstT, const CFGBlock *dstF)
This node builder keeps track of the generated sink nodes.
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
ProgramStateRef getState() const
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
SwitchStmt - This represents a 'switch' stmt.
friend class EndOfFunctionNodeBuilder
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
const StackFrameContext * getStackFrame() const
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
Stores options for the analyzer from the command line.
void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block)
Inform the CoreEngine that a basic block was aborted because it could not be completely analyzed...
bool erase(ExplodedNode *N)
const NodeBuilderContext & C
void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS)
enqueue the nodes corresponding to the end of function onto the end of path / work list...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src, const Expr *condition, CoreEngine *eng)
StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, NodeBuilder *Enclosing=nullptr)
Constructs a StmtNodeBuilder.
ProgramStateRef getState() const
CoreEngine & operator=(const CoreEngine &)=delete
NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, bool F=true)
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
iterator begin()
Iterators through the results frontier.
NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, bool F=true)
const CFGBlock * getBlock() const
CFGTerminator getTerminator() const
bool isFeasible(bool branch)
const Expr * getTarget() const
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
const LocationContext * LC