From: Ted Kremenek Date: Thu, 1 Dec 2011 00:59:21 +0000 (+0000) Subject: Specially whitelist the selector 'addOperationWithBlock:' for the retain-cycle checki... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=968a0ee9d98549308e3e70e787e4fd669d2a829d;p=clang Specially whitelist the selector 'addOperationWithBlock:' for the retain-cycle checking in -Warc-retain-cycles. This commonly is hit by users using NSOperationQueue. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145548 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index ec36963ed6..0d640a8c12 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -4533,8 +4533,14 @@ static bool isSetterLikeSelector(Selector sel) { StringRef str = sel.getNameForSlot(0); while (!str.empty() && str.front() == '_') str = str.substr(1); - if (str.startswith("set") || str.startswith("add")) + if (str.startswith("set")) str = str.substr(3); + else if (str.startswith("add")) { + // Specially whitelist 'addOperationWithBlock:'. + if (sel.getNumArgs() == 1 && str.startswith("addOperationWithBlock")) + return false; + str = str.substr(3); + } else return false; diff --git a/test/SemaObjC/warn-retain-cycle.m b/test/SemaObjC/warn-retain-cycle.m index 596858f83a..a05e663c09 100644 --- a/test/SemaObjC/warn-retain-cycle.m +++ b/test/SemaObjC/warn-retain-cycle.m @@ -89,3 +89,37 @@ void test2_helper(id); }; } @end + + +@interface NSOperationQueue {} +- (void)addOperationWithBlock:(void (^)(void))block; +- (void)addSomethingElse:(void (^)(void))block; + +@end + +@interface Test3 { + NSOperationQueue *myOperationQueue; + unsigned count; +} +@end +void doSomething(unsigned v); +@implementation Test3 +- (void) test { + // 'addOperationWithBlock:' is specifically whitelisted. + [myOperationQueue addOperationWithBlock:^() { // no-warning + if (count > 20) { + doSomething(count); + } + }]; +} +- (void) test_positive { + // Sanity check that we are really whitelisting 'addOperationWithBlock:' and not doing + // something funny. + [myOperationQueue addSomethingElse:^() { // expected-note {{block will be retained by an object strongly retained by the captured object}} + if (count > 20) { // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}} + doSomething(count); + } + }]; +} +@end +