Message ID | 20171123203556.GT14653@tucnak |
---|---|
State | New |
Headers | show |
Series | [C++] Fix structured binding initializer checking (PR c++/81888) | expand |
On Thu, Nov 23, 2017 at 3:35 PM, Jakub Jelinek <jakub@redhat.com> wrote: > 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)? Yes. Jason
--- 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> ();