Hi! For cp_finish_decomp we require that the id decl for the structured binding are chained together, because we pass just the artificial underlying decl and first id and cp_finish_decomp walks DECL_CHAIN to find other ids. tsubst_decomp_names was actually requiring not just that, but also that the artificial undering decl follows the last id, which is unnecessary and isn't actually true if the initializer has some lambdas in it, because those might appear in between.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-04-05 Jakub Jelinek <ja...@redhat.com> PR c++/85209 * pt.c (tsubst_decomp_names): Don't fail or ICE if DECL_CHAIN (decl3) is not prev, if prev == decl. * g++.dg/cpp1z/decomp39.C: New test. * g++.dg/cpp1z/decomp40.C: New test. --- gcc/cp/pt.c.jj 2018-04-05 09:49:06.155459292 +0200 +++ gcc/cp/pt.c 2018-04-05 15:02:40.290261785 +0200 @@ -16230,7 +16230,8 @@ tsubst_decomp_names (tree decl, tree pat if (error_operand_p (decl3)) decl = error_mark_node; else if (decl != error_mark_node - && DECL_CHAIN (decl3) != prev) + && DECL_CHAIN (decl3) != prev + && decl != prev) { gcc_assert (errorcount); decl = error_mark_node; --- gcc/testsuite/g++.dg/cpp1z/decomp39.C.jj 2018-04-05 15:10:17.053265429 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp39.C 2018-04-05 15:10:56.099265281 +0200 @@ -0,0 +1,16 @@ +// PR c++/85209 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +template <int> +void +foo () +{ + auto [a] = []{}; // { dg-error "cannot decompose lambda closure type" } +} // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + +void +bar () +{ + foo<0> (); +} --- gcc/testsuite/g++.dg/cpp1z/decomp40.C.jj 2018-04-05 15:11:58.630265722 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp40.C 2018-04-05 15:11:49.402265657 +0200 @@ -0,0 +1,18 @@ +// PR c++/85209 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct S { int a; } s; + +template <int> +void +foo () +{ + auto [a] = []{ return s; } (); // { dg-warning "structured bindings only available with" "" { target c++14_down } } +}; + +void +bar () +{ + foo<0> (); +} Jakub