ahatanak created this revision.
ahatanak added reviewers: rjmccall, erik.pilkington.
ahatanak added a project: clang.
ahatanak requested review of this revision.

In the following example, the block passed to the function is marked as 
`noescape`, which is incorrect as the `noescape` attribute applies to the 
reference:

  typedef void (^BlockTy)();
   __block S6 b5;
  void noescapeFuncRefParam1(__attribute__((noescape)) BlockTy &&);
  noescapeFuncRefParam1(^{ (void)b5; });

This partially fixes PR50043.

rdar://77030453


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101097

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaObjCXX/noescape.mm


Index: clang/test/SemaObjCXX/noescape.mm
===================================================================
--- clang/test/SemaObjCXX/noescape.mm
+++ 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;
+  });
 }
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -5911,7 +5911,8 @@
                (!Param || !Param->hasAttr<CFConsumedAttr>()))
         CFAudited = true;
 
-      if (Proto->getExtParameterInfo(i).isNoEscape())
+      if (Proto->getExtParameterInfo(i).isNoEscape() &&
+          !ProtoArgType->isReferenceType())
         if (auto *BE = dyn_cast<BlockExpr>(Arg->IgnoreParenNoopCasts(Context)))
           BE->getBlockDecl()->setDoesNotEscape();
 


Index: clang/test/SemaObjCXX/noescape.mm
===================================================================
--- clang/test/SemaObjCXX/noescape.mm
+++ 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;
+  });
 }
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -5911,7 +5911,8 @@
                (!Param || !Param->hasAttr<CFConsumedAttr>()))
         CFAudited = true;
 
-      if (Proto->getExtParameterInfo(i).isNoEscape())
+      if (Proto->getExtParameterInfo(i).isNoEscape() &&
+          !ProtoArgType->isReferenceType())
         if (auto *BE = dyn_cast<BlockExpr>(Arg->IgnoreParenNoopCasts(Context)))
           BE->getBlockDecl()->setDoesNotEscape();
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to