diff options
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) |