Message ID | 20170630172424.GN2123@tucnak |
---|---|
State | New |
Headers | show |
On 06/30/2017 01:24 PM, Jakub Jelinek wrote: > The initializer for structured binding has to be one of: > = assignment-expression > ( assignment-expression ) > { assignment-expression } > but cp_parser_initializer can parse other forms, with fewer or more > expressions in there. Some cases we caught with various cryptic errors > or pedwarns, but others we just ICEd on. > > The following patch attempts to check this. ok, but ... > --- gcc/testsuite/g++.dg/cpp1z/decomp21.C.jj 2017-01-19 17:01:21.000000000 +0100 > +++ gcc/testsuite/g++.dg/cpp1z/decomp21.C 2017-06-30 11:07:04.786746784 +0200 > @@ -12,5 +12,5 @@ foo () > auto [ n, o, p ] { a }; > auto [ q, r, t ] ( s ); > auto [ u, v, w ] ( s, ); // { dg-error "expected primary-expression before '.' token" } > - auto [ x, y, z ] ( a ); // { dg-error "expression list treated as compound expression in initializer" "" { target *-*-* } .-1 } > + auto [ x, y, z ] ( a ); // { dg-error "invalid initializer for structured binding" "" { target *-*-* } .-1 } > } The .-1 on the final error is actually about the previous statement, not the line it's lexically on. Could you put it on a line on its own, while you're there?
--- gcc/cp/parser.c.jj 2017-06-30 09:49:25.000000000 +0200 +++ gcc/cp/parser.c 2017-06-30 11:03:18.526521000 +0200 @@ -13196,6 +13196,15 @@ cp_parser_decomposition_declaration (cp_ *init_loc = cp_lexer_peek_token (parser->lexer)->location; tree initializer = cp_parser_initializer (parser, &is_direct_init, &non_constant_p); + if (initializer == NULL_TREE + || (TREE_CODE (initializer) == TREE_LIST + && TREE_CHAIN (initializer)) + || (TREE_CODE (initializer) == CONSTRUCTOR + && CONSTRUCTOR_NELTS (initializer) != 1)) + { + error_at (loc, "invalid initializer for structured binding"); + initializer = error_mark_node; + } if (decl != error_mark_node) { --- gcc/testsuite/g++.dg/cpp1z/decomp21.C.jj 2017-01-19 17:01:21.000000000 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp21.C 2017-06-30 11:07:04.786746784 +0200 @@ -12,5 +12,5 @@ foo () auto [ n, o, p ] { a }; auto [ q, r, t ] ( s ); auto [ u, v, w ] ( s, ); // { dg-error "expected primary-expression before '.' token" } - auto [ x, y, z ] ( a ); // { dg-error "expression list treated as compound expression in initializer" "" { target *-*-* } .-1 } + auto [ x, y, z ] ( a ); // { dg-error "invalid initializer for structured binding" "" { target *-*-* } .-1 } } --- gcc/testsuite/g++.dg/cpp1z/decomp30.C.jj 2017-06-30 11:09:31.934942575 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp30.C 2017-06-30 11:09:22.000000000 +0200 @@ -0,0 +1,12 @@ +// PR c++/81258 +// { dg-options -std=c++1z } + +int a[2]; +auto [b, c] (a); +auto [d, e] { a }; +auto [f, g] = a; +auto [h, i] ( a, a ); // { dg-error "invalid initializer for structured binding" } +auto [j, k] { a, a }; // { dg-error "invalid initializer for structured binding" } +auto [l, m] = { a }; // { dg-error "deducing from brace-enclosed initializer list requires" } +auto [n, o] {}; // { dg-error "invalid initializer for structured binding" } +auto [p, q] (); // { dg-error "invalid initializer for structured binding" }