aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp13
-rw-r--r--test/Analysis/delegates.m18
2 files changed, 27 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 99243d2b14..fc21a1ba7d 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1351,10 +1351,15 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
// 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 (StrInStrNoCase(str, "delegate:") != StringRef::npos)
- ReceiverEff = StopTracking;
+ for (unsigned i = 0, e = S.getNumArgs(); i != e; ++i) {
+ StringRef Slot = S.getNameForSlot(i);
+ if (Slot.substr(Slot.size() - 8).equals_lower("delegate")) {
+ if (ResultEff == ObjCInitRetE)
+ ResultEff = RetEffect::MakeNoRet();
+ else
+ ReceiverEff = StopTracking;
+ }
+ }
}
if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing &&
diff --git a/test/Analysis/delegates.m b/test/Analysis/delegates.m
index 8f42b83b0e..7a86671a2f 100644
--- a/test/Analysis/delegates.m
+++ b/test/Analysis/delegates.m
@@ -111,3 +111,21 @@ extern void *_NSConstantStringClassReference;
}
@end
+
+@interface ObjectThatRequiresDelegate : NSObject
+- (id)initWithDelegate:(id)delegate;
+- (id)initWithNumber:(int)num delegate:(id)delegate;
+@end
+
+
+@interface DelegateRequirerTest
+@end
+@implementation DelegateRequirerTest
+
+- (void)test {
+ (void)[[ObjectThatRequiresDelegate alloc] initWithDelegate:self];
+ (void)[[ObjectThatRequiresDelegate alloc] initWithNumber:0 delegate:self];
+ // no leak warnings -- these objects could be released in callback methods
+}
+
+@end