diff mbox series

C++ PATCH for c++/85889, reject capturing a structured binding

Message ID 20180529204441.GH3559@redhat.com
State New
Headers show
Series C++ PATCH for c++/85889, reject capturing a structured binding | expand

Commit Message

Marek Polacek May 29, 2018, 8:44 p.m. UTC
[expr.prim.lambda.capture] p8 says "If a lambda-expression explicitly captures
an entity that is not odr-usable or captures a structured binding (explicitly
or implicitly), the program is ill-formed."
but we weren't respecting that and the attached testcase compiled.  I think we
can reject such uses in add_capture.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-05-29  Marek Polacek  <polacek@redhat.com>

	PR c++/85889
	* lambda.c (add_capture): Give error when capturing a structured
	binding.

	* g++.dg/cpp1z/decomp16.C: New test.
	* g++.dg/cpp1z/decomp46.C: New test.

Comments

Jason Merrill May 29, 2018, 10:23 p.m. UTC | #1
On Tue, May 29, 2018 at 4:44 PM, Marek Polacek <polacek@redhat.com> wrote:
> [expr.prim.lambda.capture] p8 says "If a lambda-expression explicitly captures
> an entity that is not odr-usable or captures a structured binding (explicitly
> or implicitly), the program is ill-formed."

That's a pretty recent change, and seems to be controversial, so I
think let's hold off on this patch for now.

Jason
Ville Voutilainen May 29, 2018, 10:33 p.m. UTC | #2
On 30 May 2018 at 01:23, Jason Merrill <jason@redhat.com> wrote:
> On Tue, May 29, 2018 at 4:44 PM, Marek Polacek <polacek@redhat.com> wrote:
>> [expr.prim.lambda.capture] p8 says "If a lambda-expression explicitly captures
>> an entity that is not odr-usable or captures a structured binding (explicitly
>> or implicitly), the program is ill-formed."
>
> That's a pretty recent change, and seems to be controversial, so I
> think let's hold off on this patch for now.

Yep, I asked the bug to be suspended, and Jonathan did so. I very much
intend to revert this
particular change in the standard, or morph it so that capturing
bindings is clearly well-formed.
Marek Polacek May 30, 2018, 12:51 p.m. UTC | #3
On Wed, May 30, 2018 at 01:33:17AM +0300, Ville Voutilainen wrote:
> On 30 May 2018 at 01:23, Jason Merrill <jason@redhat.com> wrote:
> > On Tue, May 29, 2018 at 4:44 PM, Marek Polacek <polacek@redhat.com> wrote:
> >> [expr.prim.lambda.capture] p8 says "If a lambda-expression explicitly captures
> >> an entity that is not odr-usable or captures a structured binding (explicitly
> >> or implicitly), the program is ill-formed."
> >
> > That's a pretty recent change, and seems to be controversial, so I
> > think let's hold off on this patch for now.
> 
> Yep, I asked the bug to be suspended, and Jonathan did so. I very much
> intend to revert this
> particular change in the standard, or morph it so that capturing
> bindings is clearly well-formed.

Ack, thanks.

Marek
diff mbox series

Patch

diff --git gcc/cp/lambda.c gcc/cp/lambda.c
index 9c1b49b4d8e..c3d0decba08 100644
--- gcc/cp/lambda.c
+++ gcc/cp/lambda.c
@@ -569,6 +569,12 @@  add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
       if (type == error_mark_node)
 	return error_mark_node;
 
+      if (DECL_DECOMPOSITION_P (initializer))
+	{
+	  error ("cannot capture a structured binding %qE", initializer);
+	  return error_mark_node;
+	}
+
       if (id == this_identifier && !by_reference_p)
 	{
 	  gcc_assert (INDIRECT_TYPE_P (type));
diff --git gcc/testsuite/g++.dg/cpp1z/decomp16.C gcc/testsuite/g++.dg/cpp1z/decomp16.C
index dad69b89c08..89ed774d614 100644
--- gcc/testsuite/g++.dg/cpp1z/decomp16.C
+++ gcc/testsuite/g++.dg/cpp1z/decomp16.C
@@ -8,7 +8,7 @@  void
 foo ()
 {
   auto [ a, b ] = A ();
-  for (; auto [ a, b ] = A (); )			// { dg-error "expected|no match" }
+  for (; auto [ a, b ] = A (); )			// { dg-error "expected|no match|cannot" }
     ;
   for (; false; auto [ a, b ] = A ())			// { dg-error "expected" }
     ;
diff --git gcc/testsuite/g++.dg/cpp1z/decomp46.C gcc/testsuite/g++.dg/cpp1z/decomp46.C
index e69de29bb2d..cf5c8be6368 100644
--- gcc/testsuite/g++.dg/cpp1z/decomp46.C
+++ gcc/testsuite/g++.dg/cpp1z/decomp46.C
@@ -0,0 +1,26 @@ 
+// PR c++/85889
+// { dg-do compile }
+// { dg-options "-std=c++17" }
+
+struct X { int i, j; };
+void
+f ()
+{
+  X x{};
+  auto [i, j] = x;
+
+  auto [m, n] = X ();
+
+  [i]() { }; // { dg-error "cannot capture a structured binding" }
+  [&i]() { }; // { dg-error "cannot capture a structured binding" }
+  [j]() { }; // { dg-error "cannot capture a structured binding" }
+  [&j]() { }; // { dg-error "cannot capture a structured binding" }
+  [=]() { return i; }; // { dg-error "cannot capture a structured binding" }
+  [&]() { return i; }; // { dg-error "cannot capture a structured binding" }
+  [=]() { return j; }; // { dg-error "cannot capture a structured binding" }
+  [&]() { return j; }; // { dg-error "cannot capture a structured binding" }
+  [&, i]() { return i; }; // { dg-error "cannot capture a structured binding" }
+  [=, &i]() { return i; }; // { dg-error "cannot capture a structured binding" }
+  [&, i]() { return j; }; // { dg-error "cannot capture a structured binding" }
+  [=, &i]() { return j; }; // { dg-error "cannot capture a structured binding" }
+}