diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ExprEngine.cpp | 21 | ||||
-rw-r--r-- | lib/StaticAnalyzer/CoreEngine.cpp | 49 |
2 files changed, 59 insertions, 11 deletions
diff --git a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp index 5dd5d72a4c..e6d9d715d4 100644 --- a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp @@ -1077,11 +1077,22 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, // Block entrance. (Update counters). //===----------------------------------------------------------------------===// -bool ExprEngine::processCFGBlockEntrance(const CFGBlock* B, - const ExplodedNode *Pred, - BlockCounter BC) { - return BC.getNumVisited(Pred->getLocationContext()->getCurrentStackFrame(), - B->getBlockID()) < AMgr.getMaxVisit(); +void ExprEngine::processCFGBlockEntrance(ExplodedNodeSet &dstNodes, + GenericNodeBuilder<BlockEntrance> &nodeBuilder){ + + // FIXME: Refactor this into a checker. + const CFGBlock *block = nodeBuilder.getProgramPoint().getBlock(); + ExplodedNode *pred = nodeBuilder.getPredecessor(); + + if (nodeBuilder.getBlockCounter().getNumVisited( + pred->getLocationContext()->getCurrentStackFrame(), + block->getBlockID()) >= AMgr.getMaxVisit()) { + + static int tag = 0; + const BlockEntrance &BE = nodeBuilder.getProgramPoint(); + BlockEntrance BE_tagged(BE.getBlock(), BE.getLocationContext(), &tag); + nodeBuilder.generateNode(pred->getState(), pred, BE_tagged, true); + } } //===----------------------------------------------------------------------===// 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) |