From 43ffba26761164bcb54ad2f30d61fd845e1b98a6 Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Mon, 27 Feb 2012 23:40:55 +0000 Subject: [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 --- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp') diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 9fe34f55252..f7f199e26c3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/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(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(P).getStmt(); + if (!isa(P)) + return 0; + + return cast(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); -- cgit v1.2.3