Re: [PATCH] c++: Fix parsing of abstract-declarator starting with ... followed by [ or ( [PR115012]
On 5/9/24 14:12, Jakub Jelinek wrote: The C++26 P2662R3 Pack indexing paper mentions that both GCC and MSVC don't handle T...[10] parameter declaration when T is a pack. While that will change meaning in C++26, in C++11 .. C++23 this ought to be valid. Sure, but I don't think it does anyone any favors to start accepting a pattern that we know is going to break before long. Us not accepting it was part of the rationale for the paper. Also, T...(args) as well. This part of the patch is OK. The following patch handles those in cp_parser_direct_declarator. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-05-09 Jakub Jelinek PR c++/115012 * parser.cc (cp_parser_direct_declarator): Handle abstract declarator starting with ... followed by [ or (. * g++.dg/cpp0x/variadic185.C: New test. * g++.dg/cpp0x/variadic186.C: New test. --- gcc/cp/parser.cc.jj 2024-05-09 10:30:58.0 +0200 +++ gcc/cp/parser.cc2024-05-09 16:44:01.250777325 +0200 @@ -23916,7 +23916,12 @@ cp_parser_direct_declarator (cp_parser* { /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); - if (token->type == CPP_OPEN_PAREN) + if (token->type == CPP_OPEN_PAREN + || (first + && dcl_kind != CP_PARSER_DECLARATOR_NAMED + && token->type == CPP_ELLIPSIS + && cxx_dialect > cxx98 + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))) { /* This is either a parameter-declaration-clause, or a parenthesized declarator. When we know we are parsing a @@ -23955,6 +23960,11 @@ cp_parser_direct_declarator (cp_parser* Thus again, we try a parameter-declaration-clause, and if that fails, we back out and return. */ + bool pack_expansion_p = token->type == CPP_ELLIPSIS; + + if (pack_expansion_p) + /* Consume the `...' */ + cp_lexer_consume_token (parser->lexer); if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED) { @@ -24098,6 +24108,7 @@ cp_parser_direct_declarator (cp_parser* attrs, parens_loc); declarator->attributes = gnu_attrs; + declarator->parameter_pack_p |= pack_expansion_p; /* Any subsequent parameter lists are to do with return type, so are not those of the declared function. */ @@ -24121,7 +24132,7 @@ cp_parser_direct_declarator (cp_parser* /* If this is the first, we can try a parenthesized declarator. */ - if (first) + if (first && !pack_expansion_p) { bool saved_in_type_id_in_expr_p; @@ -24156,16 +24167,27 @@ cp_parser_direct_declarator (cp_parser* else break; } - else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED) - && token->type == CPP_OPEN_SQUARE - && !cp_next_tokens_can_be_attribute_p (parser)) + else if (((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED) + && token->type == CPP_OPEN_SQUARE + && !cp_next_tokens_can_be_attribute_p (parser)) + || (first + && dcl_kind != CP_PARSER_DECLARATOR_NAMED + && token->type == CPP_ELLIPSIS + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE) + && cxx_dialect > cxx98 + && !cp_nth_tokens_can_be_std_attribute_p (parser, 2))) { /* Parse an array-declarator. */ tree bounds, attrs; + bool pack_expansion_p = token->type == CPP_ELLIPSIS; if (ctor_dtor_or_conv_p) *ctor_dtor_or_conv_p = 0; + if (pack_expansion_p) + /* Consume the `...' */ + cp_lexer_consume_token (parser->lexer); + open_paren = NULL; first = false; parser->default_arg_ok_p = false; @@ -24220,6 +24242,7 @@ cp_parser_direct_declarator (cp_parser* attrs = cp_parser_std_attribute_spec_seq (parser); declarator = make_array_declarator (declarator, bounds); declarator->std_attributes = attrs; + declarator->parameter_pack_p |= pack_expansion_p; } else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT) { --- gcc/testsuite/g++.dg/cpp0x/variadic185.C.jj 2024-05-09 15:08:49.070651189 +0200 +++ gcc/testsuite/g++.dg/cpp0x/variadic185.C2024-05-09 15:07:40.045583153 +0200 @@ -0,0 +1,39 @@ +// PR c++/115012 +// { dg-do compile { target { c++11 && c++23_down } } } +// { dg-final { scan-assembler "_Z3fooILi10EJidEEvDpAT__T0_" } } +// { dg-final { scan-assembler "_Z3barILi10EiEvPT0_" } } +// { dg-final { scan-assembler "_Z3bazILi10EJidEEvDpAT__T0_" } } +// { dg-final { scan-assembler "_
C++ Patch ping - Re: [PATCH] c++: Fix parsing of abstract-declarator starting with ... followed by [ or ( [PR115012]
Hi! I'd like to ping the https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651199.html patch. Thanks. On Thu, May 09, 2024 at 08:12:30PM +0200, Jakub Jelinek wrote: > The C++26 P2662R3 Pack indexing paper mentions that both GCC > and MSVC don't handle T...[10] parameter declaration when T > is a pack. While that will change meaning in C++26, in C++11 .. C++23 > this ought to be valid. Also, T...(args) as well. > > The following patch handles those in cp_parser_direct_declarator. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2024-05-09 Jakub Jelinek > > PR c++/115012 > * parser.cc (cp_parser_direct_declarator): Handle > abstract declarator starting with ... followed by [ > or (. > > * g++.dg/cpp0x/variadic185.C: New test. > * g++.dg/cpp0x/variadic186.C: New test. Jakub
[PATCH] c++: Fix parsing of abstract-declarator starting with ... followed by [ or ( [PR115012]
Hi! The C++26 P2662R3 Pack indexing paper mentions that both GCC and MSVC don't handle T...[10] parameter declaration when T is a pack. While that will change meaning in C++26, in C++11 .. C++23 this ought to be valid. Also, T...(args) as well. The following patch handles those in cp_parser_direct_declarator. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-05-09 Jakub Jelinek PR c++/115012 * parser.cc (cp_parser_direct_declarator): Handle abstract declarator starting with ... followed by [ or (. * g++.dg/cpp0x/variadic185.C: New test. * g++.dg/cpp0x/variadic186.C: New test. --- gcc/cp/parser.cc.jj 2024-05-09 10:30:58.0 +0200 +++ gcc/cp/parser.cc2024-05-09 16:44:01.250777325 +0200 @@ -23916,7 +23916,12 @@ cp_parser_direct_declarator (cp_parser* { /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); - if (token->type == CPP_OPEN_PAREN) + if (token->type == CPP_OPEN_PAREN + || (first + && dcl_kind != CP_PARSER_DECLARATOR_NAMED + && token->type == CPP_ELLIPSIS + && cxx_dialect > cxx98 + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))) { /* This is either a parameter-declaration-clause, or a parenthesized declarator. When we know we are parsing a @@ -23955,6 +23960,11 @@ cp_parser_direct_declarator (cp_parser* Thus again, we try a parameter-declaration-clause, and if that fails, we back out and return. */ + bool pack_expansion_p = token->type == CPP_ELLIPSIS; + + if (pack_expansion_p) + /* Consume the `...' */ + cp_lexer_consume_token (parser->lexer); if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED) { @@ -24098,6 +24108,7 @@ cp_parser_direct_declarator (cp_parser* attrs, parens_loc); declarator->attributes = gnu_attrs; + declarator->parameter_pack_p |= pack_expansion_p; /* Any subsequent parameter lists are to do with return type, so are not those of the declared function. */ @@ -24121,7 +24132,7 @@ cp_parser_direct_declarator (cp_parser* /* If this is the first, we can try a parenthesized declarator. */ - if (first) + if (first && !pack_expansion_p) { bool saved_in_type_id_in_expr_p; @@ -24156,16 +24167,27 @@ cp_parser_direct_declarator (cp_parser* else break; } - else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED) - && token->type == CPP_OPEN_SQUARE - && !cp_next_tokens_can_be_attribute_p (parser)) + else if (((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED) + && token->type == CPP_OPEN_SQUARE + && !cp_next_tokens_can_be_attribute_p (parser)) + || (first + && dcl_kind != CP_PARSER_DECLARATOR_NAMED + && token->type == CPP_ELLIPSIS + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE) + && cxx_dialect > cxx98 + && !cp_nth_tokens_can_be_std_attribute_p (parser, 2))) { /* Parse an array-declarator. */ tree bounds, attrs; + bool pack_expansion_p = token->type == CPP_ELLIPSIS; if (ctor_dtor_or_conv_p) *ctor_dtor_or_conv_p = 0; + if (pack_expansion_p) + /* Consume the `...' */ + cp_lexer_consume_token (parser->lexer); + open_paren = NULL; first = false; parser->default_arg_ok_p = false; @@ -24220,6 +24242,7 @@ cp_parser_direct_declarator (cp_parser* attrs = cp_parser_std_attribute_spec_seq (parser); declarator = make_array_declarator (declarator, bounds); declarator->std_attributes = attrs; + declarator->parameter_pack_p |= pack_expansion_p; } else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT) { --- gcc/testsuite/g++.dg/cpp0x/variadic185.C.jj 2024-05-09 15:08:49.070651189 +0200 +++ gcc/testsuite/g++.dg/cpp0x/variadic185.C2024-05-09 15:07:40.045583153 +0200 @@ -0,0 +1,39 @@ +// PR c++/115012 +// { dg-do compile { target { c++11 && c++23_down } } } +// { dg-final { scan-assembler "_Z3fooILi10EJidEEvDpAT__T0_" } } +// { dg-final { scan-assembler "_Z3barILi10EiEvPT0_" } } +// { dg-final { scan-assembler "_Z3bazILi10EJidEEvDpAT__T0_" } } +// { dg-final { scan-assembler "_Z3quxILi5EJifEEvDpAT__AT__T0_" } } + +template +void +foo (T... x[N]) +{ +} + +template +void +bar (T [N]) +{ +} + +template +void +baz (T... [N]) +{ +} + +template +void +qux (T... [N][N]) +{ +} + +void +corge (int a[10], double b[10], int c[5][