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  <ja...@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.

--- 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 ();
+}

        Jakub

Reply via email to