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