diff options
author | Anna Zaks <ganna@apple.com> | 2012-02-28 03:07:06 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-02-28 03:07:06 +0000 |
commit | 721aa37621e047755a45b742160e21f4e879f462 (patch) | |
tree | 3382ee7fe0f181a421f7d737d848f5617dfd7937 | |
parent | 07d39a479cf8f20294407e749f9933da34ebecb7 (diff) |
[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
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp | 17 | ||||
-rw-r--r-- | test/Analysis/keychainAPI.m | 5 |
2 files changed, 15 insertions, 7 deletions
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<AllocatedData>(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<StmtPoint>(P)) + return 0; return cast<clang::PostStmt>(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); - } |