diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-01-11 06:37:47 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-01-11 06:37:47 +0000 |
commit | 27c54e57c4a012dcdf2b40cf985b70d0b9caa69e (patch) | |
tree | b2653d0bbdcbe929477a48322d975e79c97028e4 /lib/StaticAnalyzer/CoreEngine.cpp | |
parent | 7771406ac3c58d77468d9d176262ad7ae7ff5050 (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.cpp | 49 |
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) |