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*