diff mbox series

[C++] Fix structured binding range for in generic lambda inside of template (PR c++/87122)

Message ID 20180828223458.GS2218@tucnak
State New
Headers show
Series [C++] Fix structured binding range for in generic lambda inside of template (PR c++/87122) | expand

Commit Message

Jakub Jelinek Aug. 28, 2018, 10:34 p.m. UTC
Hi!

The following testcase ICEs in tsubst_decomp_names, because the earlier
tsubst_expr still with processing_template_decl called just
tsubst_decomp_names, but didn't arrange for DECL_VALUE_EXPR to be set on the
decomp identifier decls (which cp_finish_decomp does).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk and 8.x?

2018-08-28  Jakub Jelinek  <jakub@redhat.com>

	PR c++/87122
	* pt.c (tsubst_expr) <case RANGE_FOR_STMT>: If
	processing_template_decl and decl is structured binding decl, call
	cp_finish_decomp.

	* g++.dg/cpp1z/decomp47.C: New test.


	Jakub

Comments

Nathan Sidwell Aug. 29, 2018, 11:32 a.m. UTC | #1
On 08/28/2018 06:34 PM, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase ICEs in tsubst_decomp_names, because the earlier
> tsubst_expr still with processing_template_decl called just
> tsubst_decomp_names, but didn't arrange for DECL_VALUE_EXPR to be set on the
> decomp identifier decls (which cp_finish_decomp does).
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk and 8.x?
> 
> 2018-08-28  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/87122
> 	* pt.c (tsubst_expr) <case RANGE_FOR_STMT>: If
> 	processing_template_decl and decl is structured binding decl, call
> 	cp_finish_decomp.

ok thanks
diff mbox series

Patch

--- gcc/cp/pt.c.jj	2018-08-27 17:50:43.786489511 +0200
+++ gcc/cp/pt.c	2018-08-28 11:41:52.020677695 +0200
@@ -16832,6 +16832,8 @@  tsubst_expr (tree t, tree args, tsubst_f
 	    RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t);
 	    RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t);
 	    finish_range_for_decl (stmt, decl, expr);
+	    if (decomp_first && decl != error_mark_node)
+	      cp_finish_decomp (decl, decomp_first, decomp_cnt);
 	  }
 	else
 	  {
--- gcc/testsuite/g++.dg/cpp1z/decomp47.C.jj	2018-08-28 11:56:18.587275225 +0200
+++ gcc/testsuite/g++.dg/cpp1z/decomp47.C	2018-08-28 11:59:50.858747080 +0200
@@ -0,0 +1,32 @@ 
+// PR c++/87122
+// { dg-do run { target c++14 } }
+// { dg-options "" }
+
+extern "C" void abort ();
+struct S { int a, b; };
+int c;
+
+template <int N>
+void
+foo ()
+{
+  S x[4] = { { N, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
+  auto f = [](auto & y) {
+    for (auto & [ u, v ] : y)	// { dg-warning "structured bindings only available with" "" { target c++14_down } }
+      {
+	if ((u & 1) != 1 || v != u + 1 || u < N || u > 7 || (c & (1 << u))
+	    || &u != &y[v / 2 - 1].a || &v != &y[v / 2 - 1].b)
+	  abort ();
+	c |= 1 << u;
+      }
+  };
+  f (x);
+}
+
+int
+main ()
+{
+  foo<1> ();
+  if (c != 0xaa)
+    abort ();
+}