[cfe-commits] r51198 - /cfe/trunk/lib/Analysis/CFRefCount.cpp

Ted Kremenek kremenek at apple.com
Fri May 16 11:33:44 PDT 2008


Author: kremenek
Date: Fri May 16 13:33:44 2008
New Revision: 51198

URL: http://llvm.org/viewvc/llvm-project?rev=51198&view=rev
Log:
Cache leaks by the allocation site, not the leak location.

Modified:
    cfe/trunk/lib/Analysis/CFRefCount.cpp

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=51198&r1=51197&r2=51198&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri May 16 13:33:44 2008
@@ -25,6 +25,7 @@
 #include "llvm/ADT/ImmutableMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/ADT/STLExtras.h"
 #include <ostream>
 #include <sstream>
 
@@ -1740,6 +1741,7 @@
     virtual void EmitWarnings(BugReporter& BR);
     virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes);
     virtual bool isLeak() const { return true; }
+    virtual bool isCached(BugReport& R);
   };
   
   //===---------===//
@@ -1772,6 +1774,8 @@
       }
     }
     
+    SymbolID getSymbol() const { return Sym; }
+    
     virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
                                             ExplodedNode<ValueState>* N);
     
@@ -1963,37 +1967,17 @@
   return P;
 }
 
-
-PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
-                                             ExplodedNode<ValueState>* EndN) {
-  
-  if (!getBugType().isLeak())
-    return RangedBugReport::getEndPath(BR, EndN);
+static std::pair<ExplodedNode<ValueState>*,VarDecl*>
+GetAllocationSite(ExplodedNode<ValueState>* N, SymbolID Sym) {
 
   typedef CFRefCount::RefBindings RefBindings;
-
-  // Get the retain count.
-  unsigned long RetCount = 0;
-  
-  {
-    ValueState* St = EndN->getState();
-    RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
-    RefBindings::TreeTy* T = B.SlimFind(Sym);
-    assert (T);
-    RetCount = GetCount(T->getValue().second);
-  }
-
-  // We are a leak.  Walk up the graph to get to the first node where the
-  // symbol appeared.
-  
-  ExplodedNode<ValueState>* N = EndN;
   ExplodedNode<ValueState>* Last = N;
   
   // Find the first node that referred to the tracked symbol.  We also
   // try and find the first VarDecl the value was stored to.
   
   VarDecl* FirstDecl = 0;
-
+  
   while (N) {
     ValueState* St = N->getState();
     RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
@@ -2001,7 +1985,7 @@
     
     if (!T)
       break;
-
+    
     VarDecl* VD = 0;
     
     // Determine if there is an LVal binding to the symbol.
@@ -2019,15 +2003,44 @@
     }
     
     if (VD) FirstDecl = VD;
-        
+    
     Last = N;
     N = N->pred_empty() ? NULL : *(N->pred_begin());    
   }
   
-  // Get the allocate site.
+  return std::make_pair(Last, FirstDecl);
+}
+
+PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
+                                             ExplodedNode<ValueState>* EndN) {
   
-  assert (Last);
-  Stmt* FirstStmt = cast<PostStmt>(Last->getLocation()).getStmt();
+  if (!getBugType().isLeak())
+    return RangedBugReport::getEndPath(BR, EndN);
+
+  typedef CFRefCount::RefBindings RefBindings;
+
+  // Get the retain count.
+  unsigned long RetCount = 0;
+  
+  {
+    ValueState* St = EndN->getState();
+    RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
+    RefBindings::TreeTy* T = B.SlimFind(Sym);
+    assert (T);
+    RetCount = GetCount(T->getValue().second);
+  }
+
+  // We are a leak.  Walk up the graph to get to the first node where the
+  // symbol appeared, and also get the first VarDecl that tracked object
+  // is stored to.
+
+  ExplodedNode<ValueState>* AllocNode = 0;
+  VarDecl* FirstDecl = 0;
+  llvm::tie(AllocNode, FirstDecl) = GetAllocationSite(EndN, Sym);
+  
+  // Get the allocate site.  
+  assert (AllocNode);
+  Stmt* FirstStmt = cast<PostStmt>(AllocNode->getLocation()).getStmt();
 
   SourceManager& SMgr = BR.getContext().getSourceManager();
   unsigned AllocLine = SMgr.getLogicalLineNumber(FirstStmt->getLocStart());
@@ -2128,6 +2141,23 @@
     Nodes.push_back(I->first);
 }
 
+bool Leak::isCached(BugReport& R) {
+  
+  // Most bug reports are cached at the location where they occured.
+  // With leaks, we want to unique them by the location where they were
+  // allocated, and only report only a single path.
+  
+  SymbolID Sym = static_cast<CFRefReport&>(R).getSymbol();
+
+  ExplodedNode<ValueState>* AllocNode =
+    GetAllocationSite(R.getEndNode(), Sym).first;
+  
+  if (!AllocNode)
+    return false;
+  
+  return BugTypeCacheLocation::isCached(AllocNode->getLocation());
+}
+
 //===----------------------------------------------------------------------===//
 // Transfer function creation for external clients.
 //===----------------------------------------------------------------------===//





More information about the cfe-commits mailing list