diff options
-rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 11 | ||||
-rw-r--r-- | test/Rewriter/rewrite-byref-in-nested-blocks.mm | 23 |
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 26b32478b8..42afe17327 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -4373,7 +4373,6 @@ void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, // Handle specific things. if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) if (!isa<FunctionDecl>(CDRE->getDecl()) && - !CDRE->isByRef() && !isa<ParmVarDecl>(CDRE->getDecl()) && !InnerBlockValueDecls.count(CDRE->getDecl())) { InnerBlockValueDecls.insert(CDRE->getDecl()); @@ -4982,7 +4981,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i]; ValueDecl *VD = Exp->getDecl(); - if (!BlockByCopyDeclsPtrSet.count(VD)) { + if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) { // We need to save the copied-in variables in nested // blocks because it is needed at the end for some of the API generations. // See SynthesizeBlockLiterals routine. @@ -4996,6 +4995,14 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, ImportedBlockDecls.insert(VD); } } + if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) { + InnerDeclRefs.push_back(Exp); countOfInnerDecls++; + BlockDeclRefs.push_back(Exp); + BlockByRefDeclsPtrSet.insert(VD); + BlockByRefDecls.push_back(VD); + GetBlockCallExprs(Exp); + ImportedBlockDecls.insert(VD); + } } InnerDeclRefsCount.push_back(countOfInnerDecls); diff --git a/test/Rewriter/rewrite-byref-in-nested-blocks.mm b/test/Rewriter/rewrite-byref-in-nested-blocks.mm new file mode 100644 index 0000000000..c6279de5e1 --- /dev/null +++ b/test/Rewriter/rewrite-byref-in-nested-blocks.mm @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp +// radar 7692350 + +void f(void (^block)(void)); + +@interface X { + int y; +} +- (void)foo; +@end + +@implementation X +- (void)foo { + __block int kerfluffle; + f(^{ + f(^{ + y = 42; + kerfluffle = 1; + }); + }); +} +@end |