On Fri, Feb 16, 2024 at 10:47:47PM +0100, Jakub Jelinek wrote: > The following patch works.
Or yet another option would be instead of (sometimes) clearing declarator->parameter_pack_p when we diagnose this bug for error recovery ignore the this specifier. With the following patch (testsuite patch remains the same), I get excess errors though: /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:30:25: error: expansion pattern 'Selves' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:42:26: error: expansion pattern 'Selves' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:56:26: error: expansion pattern 'Selves&' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:68:27: error: expansion pattern 'Selves&' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:82:27: error: expansion pattern 'Selves&&' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:94:28: error: expansion pattern 'Selves&&' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:108:32: error: expansion pattern 'const Selves&' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:120:33: error: expansion pattern 'const Selves&' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:134:33: error: expansion pattern 'const Selves&&' contains no parameter packs /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:146:34: error: expansion pattern 'const Selves&&' contains no parameter packs though, that is e.g. on struct S0 { template<typename Selves> void g(this Selves... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } } where such an extra error would have been emitted if the this keyword was omitted. --- gcc/cp/parser.cc.jj 2024-02-16 17:38:27.802845433 +0100 +++ gcc/cp/parser.cc 2024-02-16 23:08:40.835437740 +0100 @@ -25734,22 +25734,6 @@ cp_parser_parameter_declaration (cp_pars decl_specifiers.locations[ds_this] = 0; } - if (xobj_param_p - && ((declarator && declarator->parameter_pack_p) - || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))) - { - location_t xobj_param - = make_location (decl_specifiers.locations[ds_this], - decl_spec_token_start->location, - input_location); - error_at (xobj_param, - "an explicit object parameter cannot " - "be a function parameter pack"); - /* Suppress errors that occur down the line. */ - if (declarator) - declarator->parameter_pack_p = false; - } - /* If a function parameter pack was specified and an implicit template parameter was introduced during cp_parser_parameter_declaration, change any implicit parameters introduced into packs. */ @@ -25762,9 +25746,10 @@ cp_parser_parameter_declaration (cp_pars (INNERMOST_TEMPLATE_PARMS (current_template_parms)); if (latest_template_parm_idx != template_parm_idx) - decl_specifiers.type = convert_generic_types_to_packs - (decl_specifiers.type, - template_parm_idx, latest_template_parm_idx); + decl_specifiers.type + = convert_generic_types_to_packs (decl_specifiers.type, + template_parm_idx, + latest_template_parm_idx); } if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) @@ -25794,6 +25779,21 @@ cp_parser_parameter_declaration (cp_pars } } + if (xobj_param_p + && (declarator ? declarator->parameter_pack_p + : PACK_EXPANSION_P (decl_specifiers.type))) + { + location_t xobj_param + = make_location (decl_specifiers.locations[ds_this], + decl_spec_token_start->location, + input_location); + error_at (xobj_param, + "an explicit object parameter cannot " + "be a function parameter pack"); + xobj_param_p = false; + decl_specifiers.locations[ds_this] = 0; + } + /* The restriction on defining new types applies only to the type of the parameter, not to the default argument. */ parser->type_definition_forbidden_message = saved_message; Jakub