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 | a00bccc0c5e12ad9c87c34ac34b96f1b4549a4fc (patch) | |
| tree | 9caef7ac7d02c2b7665eb8680c4fe79a1893c86d /clang/lib/StaticAnalyzer/CoreEngine.cpp | |
| parent | f82068a994572bd4417bb4c3639772592733fdab (diff) | |
| download | bcm5719-llvm-a00bccc0c5e12ad9c87c34ac34b96f1b4549a4fc.tar.gz bcm5719-llvm-a00bccc0c5e12ad9c87c34ac34b96f1b4549a4fc.zip | |
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.
llvm-svn: 123217
Diffstat (limited to 'clang/lib/StaticAnalyzer/CoreEngine.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/CoreEngine.cpp | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/CoreEngine.cpp b/clang/lib/StaticAnalyzer/CoreEngine.cpp index d5158ad1689..9ccc4472f4f 100644 --- a/clang/lib/StaticAnalyzer/CoreEngine.cpp +++ b/clang/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) |

