summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-11-15 19:11:43 +0000
committerJordan Rose <jordan_rose@apple.com>2012-11-15 19:11:43 +0000
commite37ab50a6ea6e5f6e8de81bcdd3381a882d5903b (patch)
tree4779386d961e8e1fef0bc5b63b2058326b9017ef /clang/lib/StaticAnalyzer
parentb9263cf1129973f5cc94c91016dbb415d22870e7 (diff)
downloadbcm5719-llvm-e37ab50a6ea6e5f6e8de81bcdd3381a882d5903b.tar.gz
bcm5719-llvm-e37ab50a6ea6e5f6e8de81bcdd3381a882d5903b.zip
[analyzer] Report leaks at the closing brace of a function body.
This fixes a few cases where we'd emit path notes like this: +---+ 1| v p = malloc(len); ^ |2 +---+ In general this should make path notes more consistent and more correct, especially in cases where the leak happens on the false branch of an if that jumps directly to the end of the function. There are a couple places where the leak is reported farther away from the cause; these are usually cases where there are several levels of nested braces before the end of the function. This still matches our current behavior for when there /is/ a statement after all the braces, though. llvm-svn: 168070
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporter.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp22
-rw-r--r--clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp12
3 files changed, 24 insertions, 13 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index c6689f8536d..5c14eaf2847 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1673,6 +1673,9 @@ PathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const {
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
return PathDiagnosticLocation::createOperatorLoc(B, SM);
+ if (isa<PostStmtPurgeDeadSymbols>(ErrorNode->getLocation()))
+ return PathDiagnosticLocation::createEnd(S, SM, LC);
+
return PathDiagnosticLocation::createBegin(S, SM, LC);
}
} else {
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index a98e8b49228..426d48dae2b 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -177,14 +177,15 @@ void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext& BC,
return;
}
- // Here, we call the Symbol Reaper with 0 stack context telling it to clean up
- // everything on the stack. We use LastStmt as a diagnostic statement, with
- // which the program point will be associated. However, we only want to use
- // LastStmt as a reference for what to clean up if it's a ReturnStmt;
- // otherwise, everything is dead.
+ // Here, we destroy the current location context. We use the current
+ // function's entire body as a diagnostic statement, with which the program
+ // point will be associated. However, we only want to use LastStmt as a
+ // reference for what to clean up if it's a ReturnStmt; otherwise, everything
+ // is dead.
SaveAndRestore<const NodeBuilderContext *> NodeContextRAII(currBldrCtx, &BC);
- removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt),
- Pred->getLocationContext(), LastSt,
+ const LocationContext *LCtx = Pred->getLocationContext();
+ removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
+ LCtx->getAnalysisDeclContext()->getBody(),
ProgramPoint::PostStmtPurgeDeadSymbolsKind);
}
@@ -289,9 +290,10 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
currBldrCtx = &Ctx;
// Here, we call the Symbol Reaper with 0 statement and callee location
// context, telling it to clean up everything in the callee's context
- // (and its children). We use LastSt as a diagnostic statement, which
- // which the program point will be associated.
- removeDead(BindedRetNode, CleanedNodes, 0, calleeCtx, LastSt,
+ // (and its children). We use the callee's function body as a diagnostic
+ // statement, with which the program point will be associated.
+ removeDead(BindedRetNode, CleanedNodes, 0, calleeCtx,
+ calleeCtx->getAnalysisDeclContext()->getBody(),
ProgramPoint::PostStmtPurgeDeadSymbolsKind);
currBldrCtx = 0;
} else {
diff --git a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 2ebadcaa238..cfe35251a91 100644
--- a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -588,6 +588,8 @@ PathDiagnosticLocation
}
else if (const StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
S = SP->getStmt();
+ if (isa<PostStmtPurgeDeadSymbols>(P))
+ return PathDiagnosticLocation::createEnd(S, SMng, P.getLocationContext());
}
else if (const PostImplicitCall *PIE = dyn_cast<PostImplicitCall>(&P)) {
return PathDiagnosticLocation(PIE->getLocation(), SMng);
@@ -619,12 +621,16 @@ PathDiagnosticLocation
while (NI) {
ProgramPoint P = NI->getLocation();
- if (const StmtPoint *PS = dyn_cast<StmtPoint>(&P))
+ if (const StmtPoint *PS = dyn_cast<StmtPoint>(&P)) {
S = PS->getStmt();
- else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
+ if (isa<PostStmtPurgeDeadSymbols>(P))
+ return PathDiagnosticLocation::createEnd(S, SM,
+ NI->getLocationContext());
+ break;
+ } else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
S = BE->getSrc()->getTerminator();
- if (S)
break;
+ }
NI = NI->succ_empty() ? 0 : *(NI->succ_begin());
}
OpenPOWER on IntegriCloud