[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

llvm-svn: 151592
This commit is contained in:
Anna Zaks 2012-02-27 23:40:55 +00:00
parent 9cd797aa3e
commit 43ffba2676
2 changed files with 17 additions and 9 deletions

View File

@ -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);

View File

@ -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}}
}