summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
diff options
context:
space:
mode:
authorDaniel Marjamaki <daniel.marjamaki@evidente.se>2016-10-07 14:21:08 +0000
committerDaniel Marjamaki <daniel.marjamaki@evidente.se>2016-10-07 14:21:08 +0000
commitd99ebc03f47332ca0290dbf6d39d1b4f1010b7b1 (patch)
treec6e2c9c4c3be20eaf61b96d26cd33dad5d878a2e /clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
parent0dccd1a0fd41eb29c0e072b5a5a527f5be388642 (diff)
downloadbcm5719-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.cpp22
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 {
OpenPOWER on IntegriCloud