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;
118 : SubEng(subengine), WList(
WorkList::makeDFS()),
119 BCounterFactory(G.getAllocator()), FunctionSummaries(FS) {}
149 blocksAborted.push_back(std::make_pair(block, node));
155 return blocksExhausted.begin();
158 return blocksExhausted.end();
161 return blocksAborted.begin();
164 return blocksAborted.end();
188 : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
196 return Eng.WList->getBlockCounter().getNumVisited(
212 virtual void anchor();
245 bool MarkAsSink =
false);
250 : C(Ctx), Finalized(F), HasGeneratedNodes(
false), Frontier(DstSet) {
251 Frontier.
Add(SrcNode);
256 : C(Ctx), Finalized(F), HasGeneratedNodes(
false), Frontier(DstSet) {
258 assert(hasNoSinksInFrontier());
267 return generateNodeImpl(PP, State, Pred,
false);
278 return generateNodeImpl(PP, State, Pred,
true);
283 assert(checkResults());
291 assert(checkResults());
292 return Frontier.
begin();
296 return Frontier.
end();
314 void anchor()
override;
336 sinksGenerated.push_back(N);
341 return sinksGenerated;
359 :
NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
367 :
NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
370 E = SrcSet.
end(); I != E; ++I )
403 void anchor()
override;
408 bool InFeasibleFalse;
414 :
NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
415 InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
424 :
NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
425 InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
433 return branch ? DstT : DstF;
438 InFeasibleTrue =
true;
440 InFeasibleFalse =
true;
444 return branch ? !InFeasibleTrue : !InFeasibleFalse;
458 : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
471 return cast<LabelStmt>((*I)->getLabel())->getDecl();
484 bool isSink =
false);
498 const Expr *Condition;
504 : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
518 return cast<CaseStmt>((*I)->getLabel());
537 bool isSink =
false);
bool operator!=(const iterator &X) const
succ_reverse_iterator succ_rbegin()
const LabelDecl * getLabel() const
void markInfeasible(bool branch)
succ_iterator succ_begin()
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
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.
Stmt - This represents one statement.
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)
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
ImplTy::iterator iterator
bool operator==(const iterator &X) const
bool Finalized
Specifies if the builder results have been finalized.
BlocksExhausted::const_iterator blocks_exhausted_begin() const
friend class CommonNodeBuilder
AdjacentBlocks::const_iterator const_succ_iterator
ExplodedNodeSet::iterator 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)
const StackFrameContext * getCurrentStackFrame() const
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
Represents binding an expression to a temporary.
StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, NodeBuilder *Enclosing=nullptr)
CFGBlock - 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.
Expr - This represents one expression.
ExplodedGraph & getGraph()
getGraph - Returns the exploded graph.
const Expr * getCondition() const
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()
Checkes if the results are ready.
BlocksAborted::const_iterator blocks_aborted_end() const
CFGTerminator getTerminator()
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. ...
LabelDecl - 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()
std::vector< std::pair< const CFGBlock *, const ExplodedNode * > > BlocksAborted
bool operator!=(const iterator &X) const
void insert(const ExplodedNodeSet &S)
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)
std::vector< std::pair< BlockEdge, const ExplodedNode * > > BlocksExhausted
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
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
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
bool isFeasible(bool branch)
const Expr * getTarget() const
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
const LocationContext * LC