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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70665 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index b9c9bb5..58f581a 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -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.
     
-    return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff,
-                                MayEscape);
+    RetEffect E =
+      followsFundamentalRule(S.getIdentifierInfoForSlot(0)->getName())
+      ? (isGCEnabled() ? RetEffect::MakeGCNotOwned()
+         : RetEffect::MakeOwned(RetEffect::ObjC, true))
+      : RetEffect::MakeNotOwned(RetEffect::ObjC);
+    
+    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*