]> granicus.if.org Git - clang/commitdiff
[ObjC][ARC] Honor noescape attribute for -Warc-retain-cycles
authorAlex Lorenz <arphaman@gmail.com>
Fri, 17 Nov 2017 20:44:25 +0000 (20:44 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Fri, 17 Nov 2017 20:44:25 +0000 (20:44 +0000)
rdar://35409566

Differential Revision: https://reviews.llvm.org/D40141

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

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

index 6b209cdef7c492372f4921432609c39c4de14848..e662a5c8b977c48531c4056f52acfa8f9110c31f 100644 (file)
@@ -11652,9 +11652,15 @@ void Sema::checkRetainCycles(ObjCMessageExpr *msg) {
   }
 
   // Check whether the receiver is captured by any of the arguments.
-  for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i)
-    if (Expr *capturer = findCapturingExpr(*this, msg->getArg(i), owner))
+  const ObjCMethodDecl *MD = msg->getMethodDecl();
+  for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) {
+    if (Expr *capturer = findCapturingExpr(*this, msg->getArg(i), owner)) {
+      // noescape blocks should not be retained by the method.
+      if (MD && MD->parameters()[i]->hasAttr<NoEscapeAttr>())
+        continue;
       return diagnoseRetainCycle(*this, capturer, owner);
+    }
+  }
 }
 
 /// Check a property assign to see if it's likely to cause a retain cycle.
index 4398d29e4a8cbccac2f351ebfc862df6da59e5cd..f27f1f8e041f1d1a4bfb9cb015d2a9ab22eab71e 100644 (file)
@@ -198,3 +198,15 @@ __block void(^myBlock)(void) = ^{
    };
 
 }
+
+typedef void (^a_block_t)(void);
+
+@interface HonorNoEscape
+- (void)addStuffUsingBlock:(__attribute__((noescape)) a_block_t)block;
+@end
+
+void testNoEscape(HonorNoEscape *obj) {
+  [obj addStuffUsingBlock:^{
+    (void)obj; // ok.
+  }];
+}