[cfe-commits] r70665 - in /cfe/trunk: lib/Analysis/CFRefCount.cpp test/Analysis/NSString.m

Ted Kremenek kremenek at apple.com
Sat May 2 23:08:32 PDT 2009


Author: kremenek
Date: Sun May  3 01:08:32 2009
New Revision: 70665

URL: http://llvm.org/viewvc/llvm-project?rev=70665&view=rev
Log:
Fix: <rdar://problem/6850275> CF objects returned from methods with "new" or "copy" in their name should be treated as owned

For methods that follow the "fundamental rule" and return Core
Foundation objects, treat those objects as owned by the caller.

Modified:
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/test/Analysis/NSString.m

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=70665&r1=70664&r2=70665&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Sun May  3 01:08:32 2009
@@ -621,6 +621,7 @@
   void InitializeMethodSummaries();
   
   bool isTrackedObjCObjectType(QualType T);
+  bool isTrackedCFObjectType(QualType T);
   
 private:
   
@@ -834,6 +835,14 @@
   return false;
 }
 
+bool RetainSummaryManager::isTrackedCFObjectType(QualType T) {
+  return isRefType(T, "CF") || // Core Foundation.
+         isRefType(T, "CG") || // Core Graphics.
+         isRefType(T, "DADisk") || // Disk Arbitration API.
+         isRefType(T, "DADissenter") ||
+         isRefType(T, "DASessionRef");
+}
+
 //===----------------------------------------------------------------------===//
 // Summary creation for functions (largely uses of Core Foundation).
 //===----------------------------------------------------------------------===//
@@ -1170,26 +1179,37 @@
     assert(!str.empty());
     if (CStrInCStrNoCase(&str[0], "delegate:")) ReceiverEff = StopTracking;
   }
+
   
   // Look for methods that return an owned object.
-  if (!isTrackedObjCObjectType(RetTy)) {
-    if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
-      return 0;
+  if (isTrackedObjCObjectType(RetTy)) {    
+    // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
+    //  by instance methods.
+    
+    RetEffect E =
+      followsFundamentalRule(S.getIdentifierInfoForSlot(0)->getName())
+      ? (isGCEnabled() ? RetEffect::MakeGCNotOwned()
+         : RetEffect::MakeOwned(RetEffect::ObjC, true))
+      : RetEffect::MakeNotOwned(RetEffect::ObjC);
     
-    return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff,
-                                MayEscape);
+    return getPersistentSummary(E, ReceiverEff, MayEscape);    
   }
   
-  // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
-  //  by instance methods.
+  // Look for methods that return an owned core foundation object.
+  if (isTrackedCFObjectType(RetTy)) {
+    RetEffect E =
+      followsFundamentalRule(S.getIdentifierInfoForSlot(0)->getName())
+    ? RetEffect::MakeOwned(RetEffect::CF, true)
+    : RetEffect::MakeNotOwned(RetEffect::CF);
+    
+    return getPersistentSummary(E, ReceiverEff, MayEscape);
+  }
   
-  RetEffect E =
-    followsFundamentalRule(S.getIdentifierInfoForSlot(0)->getName())
-    ? (isGCEnabled() ? RetEffect::MakeGCNotOwned()
-                     : RetEffect::MakeOwned(RetEffect::ObjC, true))
-      : RetEffect::MakeNotOwned(RetEffect::ObjC);
+  if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
+    return 0;
   
-  return getPersistentSummary(E, ReceiverEff, MayEscape);
+  return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff,
+                              MayEscape);
 }
 
 RetainSummary*

Modified: cfe/trunk/test/Analysis/NSString.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSString.m?rev=70665&r1=70664&r2=70665&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/NSString.m (original)
+++ cfe/trunk/test/Analysis/NSString.m Sun May  3 01:08:32 2009
@@ -262,7 +262,7 @@
   [string release]; // expected-warning{{Incorrect decrement of the reference count}}
 }
 
-// Test isTrackedObjectType()
+// Test isTrackedObjectType().
 typedef NSString* WonkyTypedef;
 @interface TestIsTracked
 + (WonkyTypedef)newString;
@@ -272,6 +272,22 @@
   NSString *str = [TestIsTracked newString]; // expected-warning{{Potential leak}}
 }
 
+// Test isTrackedCFObjectType().
+ at interface TestIsCFTracked
++ (CFStringRef) badNewCFString;
++ (CFStringRef) newCFString;
+ at end
+
+ at implementation TestIsCFTracked
++ (CFStringRef) newCFString {
+  return CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100); // no-warning
+}
++ (CFStringRef) badNewCFString {
+  return CFStringCreateWithFormat(kCFAllocatorDefault, ((void*)0), ((CFStringRef) __builtin___CFStringMakeConstantString ("" "%d" "")), 100); // expected-warning{{leak}}
+}
+
+
+
 // Test @synchronized
 void test_synchronized(id x) {
   @synchronized(x) {
@@ -279,3 +295,4 @@
   }
 }
 
+// Test return from method starting with 'new' or 'copy'





More information about the cfe-commits mailing list