From: Alex Lorenz Date: Fri, 17 Nov 2017 20:44:25 +0000 (+0000) Subject: [ObjC][ARC] Honor noescape attribute for -Warc-retain-cycles X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=656eb5d6f080498602779be5ce01eb9a79ad2d05;p=clang [ObjC][ARC] Honor noescape attribute for -Warc-retain-cycles 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 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 6b209cdef7..e662a5c8b9 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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()) + continue; return diagnoseRetainCycle(*this, capturer, owner); + } + } } /// Check a property assign to see if it's likely to cause a retain cycle. diff --git a/test/SemaObjC/warn-retain-cycle.m b/test/SemaObjC/warn-retain-cycle.m index 4398d29e4a..f27f1f8e04 100644 --- a/test/SemaObjC/warn-retain-cycle.m +++ b/test/SemaObjC/warn-retain-cycle.m @@ -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. + }]; +}