Fix the same false positive reported in PR 2542 and <rdar://problem/6793409>
involving an NSAnimation object delegating its release to a delegate method.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69992 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 7b16007..4961ef4 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1074,8 +1074,8 @@
 
 
 RetainSummary*
-RetainSummaryManager::getCommonMethodSummary(ObjCMessageExpr* ME, Selector S)
-{
+RetainSummaryManager::getCommonMethodSummary(ObjCMessageExpr* ME, Selector S) {
+
   if (ObjCMethodDecl *MD = ME->getMethodDecl()) {
     // Scan the method decl for 'void*' arguments.  These should be treated
     // as 'StopTracking' because they are often used with delegates.
@@ -1091,12 +1091,26 @@
       }
   }
   
+  // Any special effect for the receiver?
+  ArgEffect ReceiverEff = DoNothing;
+  
+  // If one of the arguments in the selector has the keyword 'delegate' we
+  // should stop tracking the reference count for the receiver.  This is
+  // because the reference count is quite possibly handled by a delegate
+  // method.
+  if (S.isKeywordSelector()) {
+    const std::string &str = S.getAsString();
+    assert(!str.empty());
+    if (CStrInCStrNoCase(&str[0], "delegate:")) ReceiverEff = StopTracking;
+  }
+  
   // Look for methods that return an owned object.
   if (!isTrackedObjectType(ME->getType())) {
-    if (ScratchArgs.empty())    
+    if (ScratchArgs.empty() && ReceiverEff == DoNothing)
       return 0;
     
-    return getPersistentSummary(RetEffect::MakeNoRet());
+    return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff,
+                                MayEscape);
   }
   
   // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
@@ -1108,7 +1122,7 @@
                      : RetEffect::MakeOwned(RetEffect::ObjC, true))
       : RetEffect::MakeNotOwned(RetEffect::ObjC);
   
-  return getPersistentSummary(E);
+  return getPersistentSummary(E, ReceiverEff, MayEscape);
 }
 
 RetainSummary*