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

Ted Kremenek kremenek at apple.com
Fri Mar 20 10:34:15 PDT 2009


Author: kremenek
Date: Fri Mar 20 12:34:15 2009
New Revision: 67384

URL: http://llvm.org/viewvc/llvm-project?rev=67384&view=rev
Log:
retain/release checker: Tracking autorelease counts for objects. We're still not
completely there with accurately modeling autorelease pools.

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=67384&r1=67383&r2=67384&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri Mar 20 12:34:15 2009
@@ -1440,6 +1440,28 @@
 };
 } // end clang namespace
 
+static SymbolRef GetCurrentAutoreleasePool(const GRState* state) {
+  ARStack stack = state->get<AutoreleaseStack>();
+  return stack.isEmpty() ? SymbolRef() : stack.getHead();
+}
+
+static GRStateRef SendAutorelease(GRStateRef state, ARCounts::Factory &F,
+                                  SymbolRef sym) {
+
+  SymbolRef pool = GetCurrentAutoreleasePool(state);
+  const ARCounts *cnts = state.get<AutoreleasePoolContents>(pool);
+  ARCounts newCnts(0);
+  
+  if (cnts) {
+    const unsigned *cnt = (*cnts).lookup(sym);
+    newCnts = F.Add(*cnts, sym, cnt ? *cnt  + 1 : 1);
+  }
+  else
+    newCnts = F.Add(F.GetEmptyMap(), sym, 1);
+  
+  return state.set<AutoreleasePoolContents>(pool, newCnts);
+}
+
 //===----------------------------------------------------------------------===//
 // Transfer functions.
 //===----------------------------------------------------------------------===//
@@ -1567,9 +1589,26 @@
 
 } // end anonymous namespace
 
+static void PrintPool(std::ostream &Out, SymbolRef Sym, const GRState *state) {
+  Out << ' ';
+  if (Sym.isValid())
+    Out << Sym;
+  else
+    Out << "<pool>";
+  Out << ":{";
+    
+  // Get the contents of the pool.
+  if (const ARCounts *cnts = state->get<AutoreleasePoolContents>(Sym))
+    for (ARCounts::iterator J=cnts->begin(), EJ=cnts->end(); J != EJ; ++J)
+      Out << '(' << J.getKey() << ',' << J.getData() << ')';
+
+  Out << '}';  
+}
 
 void CFRefCount::BindingsPrinter::Print(std::ostream& Out, const GRState* state,
                                         const char* nl, const char* sep) {
+  
+  
     
   RefBindings B = state->get<RefBindings>();
   
@@ -1583,15 +1622,14 @@
   }
   
   // Print the autorelease stack.
+  Out << sep << nl << "AR pool stack:";
   ARStack stack = state->get<AutoreleaseStack>();
-  if (!stack.isEmpty()) {
-    Out << sep << nl << "AR pool stack:";
   
-    for (ARStack::iterator I=stack.begin(), E=stack.end(); I!=E; ++I)
-      Out << ' ' << (*I);
-    
-    Out << nl;
-  }
+  PrintPool(Out, SymbolRef(), state);  // Print the caller's pool.
+  for (ARStack::iterator I=stack.begin(), E=stack.end(); I!=E; ++I)
+    PrintPool(Out, *I, state);
+
+  Out << nl;
 }
 
 static inline ArgEffect GetArgE(RetainSummary* Summ, unsigned idx) {
@@ -2230,6 +2268,9 @@
     case Autorelease:
       if (isGCEnabled())
         return state;
+      
+      // Update the autorelease counts.
+      state = SendAutorelease(state, ARCountFactory, sym);
 
       // Fall-through.
       





More information about the cfe-commits mailing list