]> granicus.if.org Git - clang/commitdiff
Specially whitelist the selector 'addOperationWithBlock:' for the retain-cycle checki...
authorTed Kremenek <kremenek@apple.com>
Thu, 1 Dec 2011 00:59:21 +0000 (00:59 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 1 Dec 2011 00:59:21 +0000 (00:59 +0000)
is hit by users using NSOperationQueue.  Fixes <rdar://problem/10465721>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145548 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/SemaObjC/warn-retain-cycle.m

index ec36963ed6175bfb2692acf94dee2aaf85bb31bc..0d640a8c123cafa9bce5bc983aa86233a78d998e 100644 (file)
@@ -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;
 
index 596858f83a3e267582a2eb27591147929919ed9f..a05e663c092c847bf596c79c6837415569ec98a9 100644 (file)
@@ -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
+