diff options
author | Anna Zaks <ganna@apple.com> | 2012-02-27 23:40:55 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-02-27 23:40:55 +0000 |
commit | 7752d292c97fd4b78a954c9a027b2a862be50f8b (patch) | |
tree | baf75b8ea7cca14f85591791c13190359b98589d | |
parent | e2133c86896b2728ea97a9028b97a65cdb695973 (diff) |
[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
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 19 | ||||
-rw-r--r-- | test/Analysis/malloc-interprocedural.c | 7 |
2 files changed, 17 insertions, 9 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); diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c index e67c14be42..374c4a310d 100644 --- a/test/Analysis/malloc-interprocedural.c +++ b/test/Analysis/malloc-interprocedural.c @@ -38,8 +38,10 @@ static void test11() { my_free1(data); } -static void test2() { - void * data = my_malloc2(1, 4); +static void testUniqueingByallocationSiteInTopLevelFunction() { + void *data = my_malloc2(1, 4); + data = 0; + int x = 5;// expected-warning {{Memory is never released; potential memory leak}} data = my_malloc2(1, 4);// expected-warning {{Memory is never released; potential memory leak}} } @@ -94,4 +96,3 @@ int uafAndCallsFooWithEmptyReturn() { fooWithEmptyReturn(12); return *x; // expected-warning {{Use of memory after it is freed}} } - |