From: Jakub Jelinek Date: Mon, 3 Jun 2024 21:07:08 +0000 (+0200) Subject: c++: Fix parsing of abstract-declarator starting with ... followed by opening paren... X-Git-Tag: basepoints/gcc-16~8553 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=48c3e5a4f935d6b8cd9ef7c51995e3b29ceb8be7;p=thirdparty%2Fgcc.git c++: Fix parsing of abstract-declarator starting with ... followed by opening paren [PR115012] 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. And apparently neither T...(args). While the former will change meaning in C++26, T...(args) is still valid even in C++26. The following patch handles just the T...(args) case in cp_parser_direct_declarator. 2024-06-03 Jakub Jelinek PR c++/115012 * parser.cc (cp_parser_direct_declarator): Handle abstract declarator starting with ... followed by opening paren. * g++.dg/cpp0x/variadic185.C: New test. --- diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 779625144db..3b2ad25af9f 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -23991,7 +23991,12 @@ cp_parser_direct_declarator (cp_parser* 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 @@ -24030,6 +24035,11 @@ cp_parser_direct_declarator (cp_parser* 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) { @@ -24173,6 +24183,7 @@ cp_parser_direct_declarator (cp_parser* 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. */ @@ -24196,7 +24207,7 @@ cp_parser_direct_declarator (cp_parser* 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; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic185.C b/gcc/testsuite/g++.dg/cpp0x/variadic185.C new file mode 100644 index 00000000000..2c04afeda00 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic185.C @@ -0,0 +1,43 @@ +// PR c++/115012 +// { dg-do compile { target { c++11 } } } +// { dg-final { scan-assembler "_Z3fooIJidEEvDpFT_iE" } } +// { dg-final { scan-assembler "_Z3barIiEvPFT_iE" } } +// { dg-final { scan-assembler "_Z3bazIJidEEvDpFT_iE" } } + +template +void +foo (T... x (int)) +{ +} + +template +void +bar (T (int)) +{ +} + +template +void +baz (T... (int)) +{ +} + +int +f1 (int) +{ + return 0; +} + +double +f2 (int) +{ + return 0; +} + +void +corge () +{ + foo (f1, f2); + bar (f1); + baz (f1, f2); +}