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

Ted Kremenek kremenek at apple.com
Wed Feb 18 15:28:26 PST 2009


Author: kremenek
Date: Wed Feb 18 17:28:26 2009
New Revision: 64980

URL: http://llvm.org/viewvc/llvm-project?rev=64980&view=rev
Log:
retain/release checker: Place the leak diagnostic after the last statement that
references the tracked object.

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=64980&r1=64979&r2=64980&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Wed Feb 18 17:28:26 2009
@@ -2579,22 +2579,44 @@
   SourceManager& SMgr = BR.getContext().getSourceManager();
   unsigned AllocLine =SMgr.getInstantiationLineNumber(FirstStmt->getLocStart());
 
-  // Get the leak site.  We may have multiple ExplodedNodes (one with the
-  // leak) that occur on the same line number; if the node with the leak
-  // has any immediate predecessor nodes with the same line number, find
-  // any transitive-successors that have a different statement and use that
-  // line number instead.  This avoids emiting a diagnostic like:
-  //
-  //    // 'y' is leaked.
-  //  int x = foo(y);
-  //
-  //  instead we want:
-  //
-  //  int x = foo(y);
-  //   // 'y' is leaked.
+  // Get the leak site.  We want to find the last place where the symbol
+  // was used in an expression.
+  const ExplodedNode<GRState>* LeakN = EndN;
+  Stmt *S = 0;
+  
+  while (LeakN) {
+    ProgramPoint P = LeakN->getLocation();
+
+    
+    if (const PostStmt *PS = dyn_cast<PostStmt>(&P))
+      S = PS->getStmt();
+    else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
+      S = BE->getSrc()->getTerminator();
+    
+    if (S) {
+      // Scan 'S' for uses of Sym.
+      GRStateRef state(LeakN->getState(), BR.getStateManager());
+      bool foundSymbol = false;
+    
+      for (Stmt::child_iterator I=S->child_begin(), E=S->child_end();
+            I!=E; ++I)
+        if (Expr *Ex = dyn_cast_or_null<Expr>(*I)) {
+          SVal X = state.GetSVal(Ex);
+          if (isa<loc::SymbolVal>(X) && 
+              cast<loc::SymbolVal>(X).getSymbol() == Sym){
+            foundSymbol = true;        
+            break;
+          }
+        }
+
+      if (foundSymbol)
+        break;
+    }
+    
+    LeakN = LeakN->pred_empty() ? 0 : *(LeakN->pred_begin());
+  }
   
-  Stmt* S = getStmt(BR);  // This is the statement where the leak occured.
-  assert (S);
+  assert(LeakN && S && "No leak site found.");
 
   // Generate the diagnostic.
   FullSourceLoc L(S->getLocStart(), SMgr);





More information about the cfe-commits mailing list