aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprEngine.cpp21
-rw-r--r--lib/StaticAnalyzer/CoreEngine.cpp49
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)