aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/CoreEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-01-11 06:37:47 +0000
committerTed Kremenek <kremenek@apple.com>2011-01-11 06:37:47 +0000
commit27c54e57c4a012dcdf2b40cf985b70d0b9caa69e (patch)
treeb2653d0bbdcbe929477a48322d975e79c97028e4 /lib/StaticAnalyzer/CoreEngine.cpp
parent7771406ac3c58d77468d9d176262ad7ae7ff5050 (diff)
Rework ExprEngine::processCFGBlockEntrance()
to use a node builder. This paves the way for Checkers to interpose (via a "visit" method) at the entrance to blocks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123217 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/CoreEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/CoreEngine.cpp49
1 files changed, 43 insertions, 6 deletions
diff --git a/lib/StaticAnalyzer/CoreEngine.cpp b/lib/StaticAnalyzer/CoreEngine.cpp
index d5158ad168..9ccc4472f4 100644
--- a/lib/StaticAnalyzer/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/CoreEngine.cpp
@@ -288,13 +288,29 @@ void CoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
return;
}
- // FIXME: Should we allow processCFGBlockEntrance to also manipulate state?
-
- if (SubEng.processCFGBlockEntrance(Blk, Pred, WList->getBlockCounter()))
- generateNode(BlockEntrance(Blk, Pred->getLocationContext()),
- Pred->State, Pred);
+ // Call into the subengine to process entering the CFGBlock.
+ ExplodedNodeSet dstNodes;
+ BlockEntrance BE(Blk, Pred->getLocationContext());
+ GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE);
+ SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder);
+
+ if (dstNodes.empty()) {
+ if (!nodeBuilder.hasGeneratedNode()) {
+ // Auto-generate a node and enqueue it to the worklist.
+ generateNode(BE, Pred->State, Pred);
+ }
+ }
else {
- blocksAborted.push_back(std::make_pair(L, Pred));
+ for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
+ I != E; ++I) {
+ WList->enqueue(*I);
+ }
+ }
+
+ for (llvm::SmallVectorImpl<ExplodedNode*>::const_iterator
+ I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
+ I != E; ++I) {
+ blocksAborted.push_back(std::make_pair(L, *I));
}
}
@@ -446,6 +462,27 @@ void CoreEngine::generateNode(const ProgramPoint& Loc,
if (IsNew) WList->enqueue(Node);
}
+ExplodedNode *
+GenericNodeBuilderImpl::generateNodeImpl(const GRState *state,
+ ExplodedNode *pred,
+ ProgramPoint programPoint,
+ bool asSink) {
+
+ HasGeneratedNode = true;
+ bool isNew;
+ ExplodedNode *node = engine.getGraph().getNode(programPoint, state, &isNew);
+ if (pred)
+ node->addPredecessor(pred, engine.getGraph());
+ if (isNew) {
+ if (asSink) {
+ node->markAsSink();
+ sinksGenerated.push_back(node);
+ }
+ return node;
+ }
+ return 0;
+}
+
StmtNodeBuilder::StmtNodeBuilder(const CFGBlock* b, unsigned idx,
ExplodedNode* N, CoreEngine* e,
GRStateManager &mgr)