]> granicus.if.org Git - clang/commitdiff
Improved diagnostics for leaks: now we report which variable was leaked.
authorTed Kremenek <kremenek@apple.com>
Fri, 2 May 2008 20:53:50 +0000 (20:53 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 2 May 2008 20:53:50 +0000 (20:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50588 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFRefCount.cpp

index c3da51bd125071efec54af84f9703ec03b58662e..1fbd2b94bd9ddf6c6a2c1a26af8351aea0228146 100644 (file)
@@ -1519,7 +1519,7 @@ namespace {
     virtual void getRanges(BugReporter& BR, const SourceRange*& beg,           
                            const SourceRange*& end) {
       
-      if (getBugType().isLeak())
+      if (!getBugType().isLeak())
         RangedBugReport::getRanges(BR, beg, end);
       else {
         beg = 0;
@@ -1714,14 +1714,36 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
   ExplodedNode<ValueState>* Last = N;
   typedef CFRefCount::RefBindings RefBindings;
     
-  // Find the first node that referred to the tracked symbol.
+  // 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);
-
-    if (!B.SlimFind(Sym))
+    RefBindings::TreeTy* T = B.SlimFind(Sym);
+    
+    if (!T)
       break;
+
+    VarDecl* VD = 0;
+    
+    // Determine if there is an LVal binding to the symbol.
+    for (ValueState::vb_iterator I=St->vb_begin(), E=St->vb_end(); I!=E; ++I) {
+      if (!isa<lval::SymbolVal>(I->second)  // Is the value a symbol?
+          || cast<lval::SymbolVal>(I->second).getSymbol() != Sym)
+        continue;
+      
+      if (VD) {  // Multiple decls map to this symbol.
+        VD = 0;
+        break;
+      }
+      
+      VD = I->first;
+    }
+    
+    if (VD) FirstDecl = VD;
         
     Last = N;
     N = N->pred_empty() ? NULL : *(N->pred_begin());    
@@ -1738,7 +1760,13 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& BR,
   // FIXME: Also get the name of the variable.
   
   std::ostringstream os;
-  os << "Object allocated on line " << Line << " is leaked.";
+  
+  os << "Object allocated on line " << Line;
+  
+  if (FirstDecl)
+    os << " and stored into '" << FirstDecl->getName() << '\'';
+    
+  os << " is leaked.";
   
   Stmt* S = getStmt(BR);
   assert (S);