diff options
author | Daniel Marjamaki <daniel.marjamaki@evidente.se> | 2016-10-07 14:21:08 +0000 |
---|---|---|
committer | Daniel Marjamaki <daniel.marjamaki@evidente.se> | 2016-10-07 14:21:08 +0000 |
commit | d99ebc03f47332ca0290dbf6d39d1b4f1010b7b1 (patch) | |
tree | c6e2c9c4c3be20eaf61b96d26cd33dad5d878a2e /clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | |
parent | 0dccd1a0fd41eb29c0e072b5a5a527f5be388642 (diff) | |
download | bcm5719-llvm-d99ebc03f47332ca0290dbf6d39d1b4f1010b7b1.tar.gz bcm5719-llvm-d99ebc03f47332ca0290dbf6d39d1b4f1010b7b1.zip |
[analyzer] Don't merge different return nodes in ExplodedGraph
Returns when calling an inline function should not be merged in the ExplodedGraph unless they are same.
Differential Revision: https://reviews.llvm.org/D25326
llvm-svn: 283554
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CoreEngine.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index a0f994e4f40..ea809b7067f 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -309,8 +309,19 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { assert (L.getLocationContext()->getCFG()->getExit().size() == 0 && "EXIT block cannot contain Stmts."); + // Get return statement.. + const ReturnStmt *RS = nullptr; + if (!L.getSrc()->empty()) { + if (Optional<CFGStmt> LastStmt = L.getSrc()->back().getAs<CFGStmt>()) { + if (RS = dyn_cast<ReturnStmt>(LastStmt->getStmt())) { + if (!RS->getRetValue()) + RS = nullptr; + } + } + } + // Process the final state transition. - SubEng.processEndOfFunction(BuilderCtx, Pred); + SubEng.processEndOfFunction(BuilderCtx, Pred, RS); // This path is done. Don't enqueue any more nodes. return; @@ -589,13 +600,14 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, WList->enqueue(Succ, Block, Idx+1); } -ExplodedNode *CoreEngine::generateCallExitBeginNode(ExplodedNode *N) { +ExplodedNode *CoreEngine::generateCallExitBeginNode(ExplodedNode *N, + const ReturnStmt *RS) { // Create a CallExitBegin node and enqueue it. const StackFrameContext *LocCtx = cast<StackFrameContext>(N->getLocationContext()); // Use the callee location context. - CallExitBegin Loc(LocCtx); + CallExitBegin Loc(LocCtx, RS); bool isNew; ExplodedNode *Node = G.getNode(Loc, N->getState(), false, &isNew); @@ -619,12 +631,12 @@ void CoreEngine::enqueue(ExplodedNodeSet &Set, } } -void CoreEngine::enqueueEndOfFunction(ExplodedNodeSet &Set) { +void CoreEngine::enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS) { for (ExplodedNodeSet::iterator I = Set.begin(), E = Set.end(); I != E; ++I) { ExplodedNode *N = *I; // If we are in an inlined call, generate CallExitBegin node. if (N->getLocationContext()->getParent()) { - N = generateCallExitBeginNode(N); + N = generateCallExitBeginNode(N, RS); if (N) WList->enqueue(N); } else { |