15 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
16 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
28 class ProgramPointTag;
52 typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
55 typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> >
68 std::unique_ptr<WorkList> WList;
114 : SubEng(subengine), WList(
WorkList::makeDFS()),
115 BCounterFactory(G.getAllocator()), FunctionSummaries(FS) {}
145 blocksAborted.push_back(std::make_pair(block, node));
151 return blocksExhausted.begin();
154 return blocksExhausted.end();
157 return blocksAborted.begin();
160 return blocksAborted.end();
184 :
Eng(E),
Block(B),
LC(N->getLocationContext()) { assert(B); }
192 return Eng.WList->getBlockCounter().getNumVisited(
208 virtual void anchor();
241 bool MarkAsSink =
false);
310 void anchor()
override;
355 :
NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
363 :
NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
366 E = SrcSet.
end(); I != E; ++I )
399 void anchor()
override;
404 bool InFeasibleFalse;
410 :
NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
411 InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
420 :
NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
421 InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
429 return branch ? DstT : DstF;
434 InFeasibleTrue =
true;
436 InFeasibleFalse =
true;
440 return branch ? !InFeasibleTrue : !InFeasibleFalse;
454 : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
467 return cast<LabelStmt>((*I)->getLabel())->getDecl();
480 bool isSink =
false);
494 const Expr *Condition;
500 : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
514 return cast<CaseStmt>((*I)->getLabel());
533 bool isSink =
false);
succ_reverse_iterator succ_rbegin()
ProgramStateRef getState() const
void markInfeasible(bool branch)
succ_iterator succ_begin()
CoreEngine(SubEngine &subengine, FunctionSummariesTy *FS)
Construct a CoreEngine object to analyze the provided CFG.
bool ExecuteWorkList(const LocationContext *L, unsigned Steps, ProgramStateRef InitState)
ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
const Expr * getCondition() const
This builder class is useful for generating nodes that resulted from visiting a statement. The main difference from its parent NodeBuilder is that it creates a statement specific ProgramPoint.
const LocationContext * getLocationContext() const
IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, const Expr *e, const CFGBlock *dispatch, CoreEngine *eng)
BlocksExhausted::const_iterator blocks_exhausted_end() const
~StmtNodeBuilder() override
NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, ProgramPoint &L)
BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &C, const CFGBlock *dstT, const CFGBlock *dstF)
const CFGBlock * getTargetBlock(bool branch) const
void takeNodes(const ExplodedNodeSet &S)
virtual void finalizeResults()
Allow subclasses to finalize results before result_begin() is executed.
BlocksAborted::const_iterator blocks_aborted_end() 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.
const Expr * getTarget() const
const SwitchStmt * getSwitch() const
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const LocationContext *LC, const ProgramPointTag *tag)
BlocksExhausted::const_iterator blocks_exhausted_begin() const
ImplTy::iterator iterator
const CFGBlock * getBlock() const
friend class CommonNodeBuilder
ExplodedNodeSet::iterator iterator
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
ExplodedNode * generateNodeImpl(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
void addNodes(ExplodedNode *N)
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
ExplodedNodeSet & Frontier
The frontier set - a set of nodes which need to be propagated after the builder dies.
BlocksAborted::const_iterator blocks_aborted_begin() const
Represents binding an expression to a temporary.
ProgramStateRef getState() const
const LocationContext * getLocationContext() const
StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, NodeBuilder *Enclosing=nullptr)
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
ExplodedGraph & getGraph()
getGraph - Returns the exploded graph.
This is the simplest builder which generates nodes in the ExplodedGraph.
bool hasWorkRemaining() const
void Add(ExplodedNode *N)
const ExplodedNodeSet & getResults()
bool wasBlockAborted() 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.
const LocationContext * getLocationContext() const
unsigned getBlockID() const
bool hasNoSinksInFrontier()
virtual bool checkResults()
Checkes if the results are ready.
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
void enqueueEndOfFunction(ExplodedNodeSet &Set)
enqueue the nodes corresponding to the end of function onto the end of path / work list...
CFGTerminator getTerminator()
bool wasBlocksExhausted() const
const StackFrameContext * getCurrentStackFrame() const
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
void dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc, const WorkListUnit &WU)
succ_reverse_iterator succ_rend()
ProgramPoint withTag(const ProgramPointTag *tag) const
const LabelDecl * getLabel() const
std::vector< std::pair< const CFGBlock *, const ExplodedNode * > > BlocksAborted
const CaseStmt * getCase() const
AdjacentBlocks::const_iterator const_succ_iterator
void insert(const ExplodedNodeSet &S)
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
void takeNodes(ExplodedNode *N)
void addNodes(const ExplodedNodeSet &S)
const NodeBuilderContext & getContext()
bool operator!=(const iterator &X) const
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 ...
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
friend class EndOfFunctionNodeBuilder
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
WorkList * getWorkList() const
std::vector< std::pair< BlockEdge, const ExplodedNode * > > BlocksExhausted
bool operator!=(const iterator &X) const
void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block)
bool erase(ExplodedNode *N)
const NodeBuilderContext & C
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. If the builder is going to process nodes currently owned by another bui...
const CFGBlock * getBlock() const
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, bool F=true)
bool operator==(const iterator &X) const
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 SmallVectorImpl< ExplodedNode * > & getSinks() const
bool isFeasible(bool branch)
const LocationContext * LC