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

Ted Kremenek kremenek at apple.com
Thu Apr 24 16:57:27 PDT 2008


Author: kremenek
Date: Thu Apr 24 18:57:27 2008
New Revision: 50237

URL: http://llvm.org/viewvc/llvm-project?rev=50237&view=rev
Log:
Add preliminary support for flagging leaks around when they happen (doesn't work yet).

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=50237&r1=50236&r2=50237&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Thu Apr 24 18:57:27 2008
@@ -684,6 +684,13 @@
   virtual void EvalEndPath(GRExprEngine& Engine,
                            GREndPathNodeBuilder<ValueState>& Builder);
   
+  virtual void EvalDeadSymbols(ExplodedNodeSet<ValueState>& Dst,
+                               GRExprEngine& Engine,
+                               GRStmtNodeBuilder<ValueState>& Builder,
+                               ProgramPoint P, ExplodedNode<ValueState>* Pred,
+                               ValueState* St,
+                               const ValueStateManager::DeadSymbolsTy& Dead);
+  
   // Return statements.
   
   virtual void EvalReturn(ExplodedNodeSet<ValueState>& Dst,
@@ -1066,10 +1073,13 @@
     
     if (hasLeak) Leaked.push_back((*I).first);
   }
-      
+
+  if (Leaked.empty())
+    return;
+  
   ExplodedNode<ValueState>* N = Builder.MakeNode(St);  
   
-  if (!N || Leaked.empty())
+  if (!N)
     return;
     
   std::vector<SymbolID>*& LeaksAtNode = Leaks[N];
@@ -1081,6 +1091,64 @@
     (*LeaksAtNode).push_back(*I);
 }
 
+// Dead symbols.
+
+void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<ValueState>& Dst,
+                                 GRExprEngine& Eng,
+                                 GRStmtNodeBuilder<ValueState>& Builder,
+                                 ProgramPoint P, ExplodedNode<ValueState>* Pred,
+                                 ValueState* St,
+                                 const ValueStateManager::DeadSymbolsTy& Dead) {
+  
+  // FIXME: Have GRStmtNodeBuilder handle the case where 'P' is not PostStmt;
+  //  This won't result in missed leaks; we'll just flag these ones at the
+  //  end-of-path.
+  
+  Stmt* S = NULL;
+  
+  if (!isa<PostStmt>(P))
+    return;
+  
+  S = cast<PostStmt>(P).getStmt();
+  
+  // FIXME: a lot of copy-and-paste from EvalEndPath.  Refactor.
+  
+  RefBindings B = GetRefBindings(*St);
+  llvm::SmallVector<SymbolID, 10> Leaked;
+  
+  for (ValueStateManager::DeadSymbolsTy::const_iterator
+       I=Dead.begin(), E=Dead.end(); I!=E; ++I) {
+    
+    RefBindings::TreeTy* T = B.SlimFind(*I);
+
+    if (!T)
+      continue;
+    
+    bool hasLeak = false;
+    
+    St = HandleSymbolDeath(Eng.getStateManager(), St,
+                           *I, T->getValue().second, hasLeak);
+    
+    if (hasLeak) Leaked.push_back(*I);    
+  }
+  
+  if (Leaked.empty())
+    return;    
+  
+  ExplodedNode<ValueState>* N = Builder.MakeNode(Dst, S, Pred, St);  
+  
+  if (!N)
+    return;
+  
+  std::vector<SymbolID>*& LeaksAtNode = Leaks[N];
+  assert (!LeaksAtNode);
+  LeaksAtNode = new std::vector<SymbolID>();
+  
+  for (llvm::SmallVector<SymbolID, 10>::iterator I=Leaked.begin(),
+       E = Leaked.end(); I != E; ++I)
+    (*LeaksAtNode).push_back(*I);    
+}
+
  // Return statements.
 
 void CFRefCount::EvalReturn(ExplodedNodeSet<ValueState>& Dst,





More information about the cfe-commits mailing list