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

Ted Kremenek kremenek at apple.com
Mon Feb 23 09:45:03 PST 2009


Author: kremenek
Date: Mon Feb 23 11:45:03 2009
New Revision: 65328

URL: http://llvm.org/viewvc/llvm-project?rev=65328&view=rev
Log:
Add more boilerplate logic to more accurately reason about autorelease pools.
This doesn't change the current functionality, but better codifies the
autorelease pool stack itself.

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=65328&r1=65327&r2=65328&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Mon Feb 23 11:45:03 2009
@@ -221,7 +221,8 @@
                  DecRefMsg, DecRef,
                  MakeCollectable,
                  DoNothing, DoNothingByRef,
-                 StopTracking, MayEscape, SelfOwn, Autorelease };
+                 StopTracking, MayEscape, SelfOwn, Autorelease,
+                 NewAutoreleasePool };
 
 /// ArgEffects summarizes the effects of a function/method call on all of
 /// its arguments.
@@ -1132,6 +1133,12 @@
   Summ = getPersistentSummary(E, Autorelease);
   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
   
+  // Specially handle NSAutoreleasePool.
+  addInstMethSummary("NSAutoreleasePool",
+                     getPersistentSummary(RetEffect::MakeReceiverAlias(),
+                                          NewAutoreleasePool),
+                     "init", NULL);
+  
   // For NSWindow, allocated objects are (initially) self-owned.  
   // FIXME: For now we opt for false negatives with NSWindow, as these objects
   //  self-own themselves.  However, they only do this once they are displayed.
@@ -1354,13 +1361,50 @@
 // ARBindings - State used to track objects in autorelease pools.
 //===----------------------------------------------------------------------===//
 
-typedef llvm::ImmutableSet<SymbolRef> ARPoolContents;
-typedef llvm::ImmutableList< std::pair<SymbolRef, ARPoolContents*> > ARBindings;
+
+namespace {
+class VISIBILITY_HIDDEN AutoreleasePoolID {
+  unsigned short PoolLevel;
+  SymbolRef Sym;
+
+public:
+  AutoreleasePoolID() : PoolLevel(0) {}
+  AutoreleasePoolID(unsigned short poolLevel, SymbolRef sym)
+    : PoolLevel(poolLevel), Sym(Sym) {}
+  
+  bool operator<(const AutoreleasePoolID &X) const {
+    assert(!(PoolLevel == X.PoolLevel) || Sym == X.Sym);
+    return PoolLevel < X.PoolLevel;
+  }
+  
+  bool operator==(const AutoreleasePoolID &X) const {
+    assert(!(PoolLevel == X.PoolLevel) || Sym == X.Sym);
+    return PoolLevel == X.PoolLevel;
+  }
+  
+  bool matches(SymbolRef sym) {
+    return Sym.isInitialized() ? Sym == sym : false;
+  }
+  
+  static void Profile(llvm::FoldingSetNodeID& ID, const AutoreleasePoolID& AI) {
+    ID.AddInteger(AI.PoolLevel);
+    if (AI.Sym.isInitialized()) ID.Add(AI.Sym);
+  }
+};
+}
+
+typedef llvm::ImmutableSet<SymbolRef> AutoreleasePoolContents;
+typedef llvm::ImmutableMap<AutoreleasePoolID, AutoreleasePoolContents>
+        AutoreleaseBindings;
+
 static int AutoRBIndex = 0;
 
+// We can use 'AutoreleaseBindings' directly as the tag class into the GDM sinc
+// it is an ImmutableMap based on two types private to this source file.
 namespace clang {
   template<>
-  struct GRStateTrait<ARBindings> : public GRStatePartialTrait<ARBindings> {
+  struct GRStateTrait<AutoreleaseBindings>
+    : public GRStatePartialTrait<AutoreleaseBindings> {
     static inline void* GDMIndex() { return &AutoRBIndex; }  
   };
 }
@@ -2040,6 +2084,8 @@
     case IncRefMsg: E = isGCEnabled() ? DoNothing : IncRef; break;
     case DecRefMsg: E = isGCEnabled() ? DoNothing : DecRef; break;
     case MakeCollectable: E = isGCEnabled() ? DecRef : DoNothing; break;
+    case NewAutoreleasePool: E = isGCEnabled() ? DoNothing : 
+                                                 NewAutoreleasePool; break;
   }
   
   switch (E) {
@@ -2052,6 +2098,8 @@
         break;
       }
       // Fall-through.
+
+    case NewAutoreleasePool: // FIXME: Implement pushing the pool to the stack.
     case DoNothingByRef:
     case DoNothing:
       if (!isGCEnabled() && V.getKind() == RefVal::Released) {





More information about the cfe-commits mailing list