]> granicus.if.org Git - clang/commitdiff
[analyzer] Leaks should be uniqued by the allocation point in the
authorAnna Zaks <ganna@apple.com>
Tue, 28 Feb 2012 03:07:06 +0000 (03:07 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 28 Feb 2012 03:07:06 +0000 (03:07 +0000)
closest function context (Keychain API).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151613 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
test/Analysis/keychainAPI.m

index f94e20db2112019a193f35b7dcddf2673f08c91c..b96bc66b6f79678450550636811774fed3552d44 100644 (file)
@@ -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));
index 21cc745b0f57be98d0c8deec00a6c83dba48e719..50aa4efbb9ae3282c72a6f994b8dd0c686089142 100644 (file)
@@ -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);
-
 }