]> granicus.if.org Git - clang/commitdiff
retain/release checker: Implement basic tracking of autorelease stack. Next thing...
authorTed Kremenek <kremenek@apple.com>
Wed, 25 Feb 2009 02:54:57 +0000 (02:54 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 25 Feb 2009 02:54:57 +0000 (02:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65425 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFRefCount.cpp

index 652b65f6488a782c97812fd5789578e294b97ef3..70d473b019db44c0794e52fc3613dd8b1e747caa 100644 (file)
@@ -646,6 +646,13 @@ private:
     ObjCMethodSummaries[S] = Summ;
   }
   
+  void addInstMethSummary(const char* Cls, const char* nullaryName,
+                          RetainSummary *Summ) {
+    IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
+    Selector S = GetNullarySelector(nullaryName, Ctx);
+    ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
+  }
+    
   void addInstMethSummary(const char* Cls, RetainSummary* Summ, va_list argp) {
     
     IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
@@ -1134,10 +1141,9 @@ void RetainSummaryManager::InitializeMethodSummaries() {
   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
   
   // Specially handle NSAutoreleasePool.
-  addInstMethSummary("NSAutoreleasePool",
+  addInstMethSummary("NSAutoreleasePool", "init",
                      getPersistentSummary(RetEffect::MakeReceiverAlias(),
-                                          NewAutoreleasePool),
-                     "init", NULL);
+                                          NewAutoreleasePool));
   
   // For NSWindow, allocated objects are (initially) self-owned.  
   // FIXME: For now we opt for false negatives with NSWindow, as these objects
@@ -1369,10 +1375,10 @@ static int AutoRCIndex = 0;
 static int AutoRBIndex = 0;
 
 namespace { class VISIBILITY_HIDDEN AutoreleasePoolContents {}; }
-namespace { class VISIBILITY_HIDDEN AutoreleaseBindings {}; }
+namespace { class VISIBILITY_HIDDEN AutoreleaseStack {}; }
 
 namespace clang {
-template<> struct GRStateTrait<AutoreleaseBindings>
+template<> struct GRStateTrait<AutoreleaseStack>
   : public GRStatePartialTrait<ARStack> {
   static inline void* GDMIndex() { return &AutoRBIndex; }  
 };
@@ -1522,6 +1528,17 @@ void CFRefCount::BindingsPrinter::Print(std::ostream& Out, const GRState* state,
     (*I).second.print(Out);
     Out << nl;
   }
+  
+  // Print the autorelease 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;
+  }
 }
 
 static inline ArgEffect GetArgE(RetainSummary* Summ, unsigned idx) {
@@ -2067,7 +2084,10 @@ GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym,
       }
       // Fall-through.
 
-    case NewAutoreleasePool: // FIXME: Implement pushing the pool to the stack.
+    case NewAutoreleasePool:
+      assert(!isGCEnabled());
+      return state.add<AutoreleaseStack>(sym);
+      
     case DoNothingByRef:
     case DoNothing:
       if (!isGCEnabled() && V.getKind() == RefVal::Released) {