diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/Core/CoreEngine.cpp | 14 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 32 |
2 files changed, 20 insertions, 26 deletions
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp index f303c7af3a..de94f0f2dd 100644 --- a/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -263,15 +263,16 @@ void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc, } } -void CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L, +bool CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, ProgramStateRef InitState, ExplodedNodeSet &Dst) { - ExecuteWorkList(L, Steps, InitState); + bool DidNotFinish = ExecuteWorkList(L, Steps, InitState); for (ExplodedGraph::eop_iterator I = G->eop_begin(), E = G->eop_end(); I != E; ++I) { Dst.Add(*I); } + return DidNotFinish; } void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { @@ -296,7 +297,7 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { ExplodedNodeSet dstNodes; BlockEntrance BE(Blk, Pred->getLocationContext()); NodeBuilderWithSinks nodeBuilder(Pred, dstNodes, BuilderCtx, BE); - SubEng.processCFGBlockEntrance(nodeBuilder); + SubEng.processCFGBlockEntrance(L, nodeBuilder); // Auto-generate a node. if (!nodeBuilder.hasGeneratedNodes()) { @@ -305,13 +306,6 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { // Enqueue nodes onto the worklist. enqueue(dstNodes); - - // Make sink nodes as exhausted. - const SmallVectorImpl<ExplodedNode*> &Sinks = nodeBuilder.getSinks(); - for (SmallVectorImpl<ExplodedNode*>::const_iterator - I =Sinks.begin(), E = Sinks.end(); I != E; ++I) { - blocksExhausted.push_back(std::make_pair(L, *I)); - } } void CoreEngine::HandleBlockEntrance(const BlockEntrance &L, diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index c47b7f4eb5..a53ffd4eb5 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -53,11 +53,6 @@ STATISTIC(NumMaxBlockCountReachedInInlined, STATISTIC(NumTimesRetriedWithoutInlining, "The # of times we re-evaluated a call without inlining"); -STATISTIC(NumNotNew, - "Cached out"); -STATISTIC(NumNull, - "Null node"); - //===----------------------------------------------------------------------===// // Utility functions. //===----------------------------------------------------------------------===// @@ -1005,10 +1000,8 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N, break; } - if (!BeforeProcessingCall) { - NumNull++; + if (!BeforeProcessingCall) return false; - } // TODO: Clean up the unneeded nodes. @@ -1024,10 +1017,11 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N, // Make the new node a successor of BeforeProcessingCall. bool IsNew = false; ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew); - if (!IsNew) { - NumNotNew++; - return false; - } + // We cached out at this point. Caching out is common due to us backtracking + // from the inlined function, which might spawn several paths. + if (!IsNew) + return true; + NewNode->addPredecessor(BeforeProcessingCall, G); // Add the new node to the work list. @@ -1038,14 +1032,16 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N, } /// Block entrance. (Update counters). -void ExprEngine::processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) { +void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, + NodeBuilderWithSinks &nodeBuilder) { // FIXME: Refactor this into a checker. ExplodedNode *pred = nodeBuilder.getContext().getPred(); if (nodeBuilder.getContext().getCurrentBlockCount() >= AMgr.getMaxVisit()) { static SimpleProgramPointTag tag("ExprEngine : Block count exceeded"); - nodeBuilder.generateNode(pred->getState(), pred, &tag, true); + const ExplodedNode *Sink = + nodeBuilder.generateNode(pred->getState(), pred, &tag, true); // Check if we stopped at the top level function or not. // Root node should have the location context of the top most function. @@ -1057,10 +1053,14 @@ void ExprEngine::processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) { // no-inlining policy in the state and enqueuing the new work item on // the list. Replay should almost never fail. Use the stats to catch it // if it does. - if (!(AMgr.RetryExhausted && replayWithoutInlining(pred, CalleeLC))) - NumMaxBlockCountReachedInInlined++; + if ((AMgr.RetryExhausted && replayWithoutInlining(pred, CalleeLC))) + return; + NumMaxBlockCountReachedInInlined++; } else NumMaxBlockCountReached++; + + // Make sink nodes as exhausted(for stats) only if retry failed. + Engine.blocksExhausted.push_back(std::make_pair(L, Sink)); } } |