diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5911,7 +5911,8 @@ (!Param || !Param->hasAttr())) CFAudited = true; - if (Proto->getExtParameterInfo(i).isNoEscape()) + if (Proto->getExtParameterInfo(i).isNoEscape() && + !ProtoArgType->isReferenceType()) if (auto *BE = dyn_cast(Arg->IgnoreParenNoopCasts(Context))) BE->getBlockDecl()->setDoesNotEscape(); diff --git a/clang/test/SemaObjCXX/noescape.mm b/clang/test/SemaObjCXX/noescape.mm --- a/clang/test/SemaObjCXX/noescape.mm +++ b/clang/test/SemaObjCXX/noescape.mm @@ -131,7 +131,7 @@ struct S6 { S6(); - S6(const S6 &) = delete; // expected-note 3 {{'S6' has been explicitly marked deleted here}} + S6(const S6 &) = delete; // expected-note 5 {{'S6' has been explicitly marked deleted here}} int f; }; @@ -143,6 +143,8 @@ __block S6 b1; // expected-error {{call to deleted constructor of 'S6'}} __block S6 b2; // expected-error {{call to deleted constructor of 'S6'}} __block S6 b3; // expected-error {{call to deleted constructor of 'S6'}} + __block S6 b4; // expected-error {{call to deleted constructor of 'S6'}} + __block S6 b5; // expected-error {{call to deleted constructor of 'S6'}} noescapeFunc0(a, ^{ (void)b0; }); escapingFunc0(^{ (void)b1; }); @@ -151,4 +153,14 @@ } noescapeFunc0(a, ^{ escapingFunc0(^{ (void)b2; }); }); escapingFunc0(^{ noescapeFunc0(a, ^{ (void)b3; }); }); + + void noescapeFuncRefParam0(__attribute__((noescape)) const BlockTy &); + noescapeFuncRefParam0(^{ + (void)b4; + }); + + void noescapeFuncRefParam1(__attribute__((noescape)) BlockTy &&); + noescapeFuncRefParam1(^{ + (void)b5; + }); }