From: Anna Zaks Date: Tue, 28 Feb 2012 03:07:06 +0000 (+0000) Subject: [analyzer] Leaks should be uniqued by the allocation point in the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=721aa37621e047755a45b742160e21f4e879f462;p=clang [analyzer] Leaks should be uniqued by the allocation point in the closest function context (Keychain API). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151613 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp index f94e20db21..b96bc66b6f 100644 --- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -503,10 +503,12 @@ void MacOSKeychainAPIChecker::checkPreStmt(const ReturnStmt *S, C.addTransition(state); } +// TODO: This logic is the same as in Malloc checker. const Stmt * MacOSKeychainAPIChecker::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; @@ -514,11 +516,16 @@ MacOSKeychainAPIChecker::getAllocationSite(const ExplodedNode *N, 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(); + if (!isa(P)) + return 0; return cast(P).getStmt(); } @@ -536,10 +543,10 @@ BugReport *MacOSKeychainAPIChecker:: // 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, AP.first, C); - PathDiagnosticLocation LocUsedForUniqueing = - PathDiagnosticLocation::createBegin(AllocStmt, C.getSourceManager(), - N->getLocationContext()); + PathDiagnosticLocation LocUsedForUniqueing; + if (const Stmt *AllocStmt = getAllocationSite(N, AP.first, C)) + LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocStmt, + C.getSourceManager(), N->getLocationContext()); BugReport *Report = new BugReport(*BT, os.str(), N, LocUsedForUniqueing); Report->addVisitor(new SecKeychainBugVisitor(AP.first)); diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m index 21cc745b0f..50aa4efbb9 100644 --- a/test/Analysis/keychainAPI.m +++ b/test/Analysis/keychainAPI.m @@ -393,8 +393,10 @@ void allocAndFree2(void *attrList) { void allocNoFree3() { UInt32 length = 32; - void *outData; + void *outData; + void *outData2; OSStatus st = my_Allocate_Param(&outData, &length); // expected-warning{{Allocated data is not released}} + st = my_Allocate_Param(&outData2, &length); // expected-warning{{Allocated data is not released}} } void allocAndFree3(void *attrList) { @@ -403,6 +405,5 @@ void allocAndFree3(void *attrList) { OSStatus st = my_Allocate_Param(&outData, &length); if (st == noErr) SecKeychainItemFreeContent(attrList, outData); - }