Hi! My PR81258 fix actually rejects even valid cases. The standard says that: "The initializer shall be of the form “= assignment-expression”, of the form “{ assignment-expression }”, or of the form “( assignment-expression )” Now, if the form is = assigment-expression, we can e.g. in templates end up with CONSTRUCTOR initializer which has more or fewer elements than 1.
So, this patch restricts the checks to only BRACE_ENCLOSED_INITIALIZER_P and only if is_direct_init (i.e. not the = assignment-expression form). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk (and 7.x after a while)? 2017-11-23 Jakub Jelinek <ja...@redhat.com> PR c++/81888 * parser.c (cp_parser_decomposition_declaration): Reject just BRACE_ENCLOSED_INITIALIZER_P initializers with nelts != 1 rather than all such CONSTRUCTORs, and only if is_direct_init is true. * g++.dg/cpp1z/decomp30.C: Add a test for structured binding with = {} and = { a, a } initializers. * g++.dg/cpp1z/decomp31.C: New test. --- gcc/cp/parser.c.jj 2017-11-21 20:23:01.000000000 +0100 +++ gcc/cp/parser.c 2017-11-23 15:31:44.473524252 +0100 @@ -13382,7 +13382,8 @@ cp_parser_decomposition_declaration (cp_ if (initializer == NULL_TREE || (TREE_CODE (initializer) == TREE_LIST && TREE_CHAIN (initializer)) - || (TREE_CODE (initializer) == CONSTRUCTOR + || (is_direct_init + && BRACE_ENCLOSED_INITIALIZER_P (initializer) && CONSTRUCTOR_NELTS (initializer) != 1)) { error_at (loc, "invalid initializer for structured binding " --- gcc/testsuite/g++.dg/cpp1z/decomp30.C.jj 2017-09-15 18:11:04.000000000 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp30.C 2017-11-23 15:33:04.208552682 +0100 @@ -10,3 +10,5 @@ auto [j, k] { a, a }; // { dg-error "inv auto [l, m] = { a }; // { dg-error "deducing from brace-enclosed initializer list requires" } auto [n, o] {}; // { dg-error "invalid initializer for structured binding declaration" } auto [p, q] (); // { dg-error "invalid initializer for structured binding declaration" } +auto [r, s] = {}; // { dg-error "deducing from brace-enclosed initializer list requires" } +auto [t, u] = { a, a }; // { dg-error "deducing from brace-enclosed initializer list requires" } --- gcc/testsuite/g++.dg/cpp1z/decomp31.C.jj 2017-11-23 15:22:31.695255014 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp31.C 2017-11-23 15:22:21.000000000 +0100 @@ -0,0 +1,18 @@ +// PR c++/81888 +// { dg-do compile { target c++17 } } + +struct S { + bool s = true; +}; + +auto [a] = S{}; + +template <class T> +bool +foo () noexcept +{ + auto [c] = T{}; + return c; +} + +const bool b = foo<S> (); Jakub