summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-02-27 23:40:55 +0000
committerAnna Zaks <ganna@apple.com>2012-02-27 23:40:55 +0000
commit7752d292c97fd4b78a954c9a027b2a862be50f8b (patch)
treebaf75b8ea7cca14f85591791c13190359b98589d /lib
parente2133c86896b2728ea97a9028b97a65cdb695973 (diff)
downloadclang-7752d292c97fd4b78a954c9a027b2a862be50f8b.tar.gz
clang-7752d292c97fd4b78a954c9a027b2a862be50f8b.tar.bz2
clang-7752d292c97fd4b78a954c9a027b2a862be50f8b.tar.xz
[analyzer] Leaks should be uniqued by the allocation point in the
closest function context. This prevents us from uniqueing all leaks from the same allocation helper. radar://10932226 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151592 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp19
1 files changed, 13 insertions, 6 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 9fe34f5525..f7f199e26c 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -775,6 +775,7 @@ ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){
const Stmt *
MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
CheckerContext &C) const {
+ const LocationContext *LeakContext = N->getLocationContext();
// Walk the ExplodedGraph backwards and find the first node that referred to
// the tracked symbol.
const ExplodedNode *AllocNode = N;
@@ -782,12 +783,18 @@ MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
while (N) {
if (!N->getState()->get<RegionState>(Sym))
break;
- AllocNode = N;
+ // Allocation node, is the last node in the current context in which the
+ // symbol was tracked.
+ if (N->getLocationContext() == LeakContext)
+ AllocNode = N;
N = N->pred_empty() ? NULL : *(N->pred_begin());
}
ProgramPoint P = AllocNode->getLocation();
- return cast<clang::PostStmt>(P).getStmt();
+ if (!isa<StmtPoint>(P))
+ return 0;
+
+ return cast<StmtPoint>(P).getStmt();
}
void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
@@ -806,10 +813,10 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
// Most bug reports are cached at the location where they occurred.
// With leaks, we want to unique them by the location where they were
// allocated, and only report a single path.
- const Stmt *AllocStmt = getAllocationSite(N, Sym, C);
- PathDiagnosticLocation LocUsedForUniqueing =
- PathDiagnosticLocation::createBegin(AllocStmt, C.getSourceManager(),
- N->getLocationContext());
+ PathDiagnosticLocation LocUsedForUniqueing;
+ if (const Stmt *AllocStmt = getAllocationSite(N, Sym, C))
+ LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocStmt,
+ C.getSourceManager(), N->getLocationContext());
BugReport *R = new BugReport(*BT_Leak,
"Memory is never released; potential memory leak", N, LocUsedForUniqueing);