On Fri, Feb 16, 2024 at 03:47:41PM -0500, Jason Merrill wrote: > Can we move all the xobj handling down here (where we can trust > declarator->parameter_pack_p) instead of adding a new variable?
I've tried that (see below), but am getting Excess errors: /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:33:29: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:45:30: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:58:23: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:59:30: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:62:25: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:70:24: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:71:31: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:74:26: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:84:24: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:85:31: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:88:26: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:96:25: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:97:32: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:100:27: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:110:29: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:111:36: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:114:31: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:122:30: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:123:37: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:126:32: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:136:30: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:137:37: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:140:32: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:148:31: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:149:38: error: parameter packs not expanded with '...': /usr/src/gcc/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C:152:33: error: parameter packs not expanded with '...': with it (the other errors are emitted as expected). 2024-02-16 Jakub Jelinek <ja...@redhat.com> PR c++/113802 * parser.cc (cp_parser_parameter_declaration): Move the xobj_param_p pack diagnostics after ellipsis handling. Formatting fix. * g++.dg/cpp23/explicit-obj-diagnostics3.C (S0, S1, S2, S3, S4): Don't expect any diagnostics on f and fd member function templates, add similar templates with ...Selves instead of Selves as k and kd and expect diagnostics for those. --- gcc/cp/parser.cc.jj 2024-02-16 17:38:27.802845433 +0100 +++ gcc/cp/parser.cc 2024-02-16 22:10:32.904353402 +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,22 @@ 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"); + /* Suppress errors that occur down the line. */ + if (declarator) + declarator->parameter_pack_p = false; + } + /* 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; --- gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C.jj 2024-02-15 20:01:40.349239387 +0100 +++ gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C 2024-02-16 21:57:48.269851483 +0100 @@ -24,7 +24,7 @@ void S::f12(this S s = {}) {} // { dg-er struct S0 { template<typename Selves> - void f(this Selves...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves...) {} template<typename Selves> void g(this Selves... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } @@ -32,19 +32,25 @@ struct S0 { void h(this auto...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } void j(this auto... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename ...Selves> + void k(this Selves...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename Selves> - void fd(this Selves...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves...); template<typename Selves> void gd(this Selves... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void hd(this auto...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void jd(this auto... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + + template<typename ...Selves> + void kd(this Selves...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S1 { template<typename Selves> - void f(this Selves&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves&...) {} template<typename Selves> void g(this Selves&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } @@ -52,19 +58,25 @@ struct S1 { void h(this auto&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } void j(this auto&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename ...Selves> + void k(this Selves&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename Selves> - void fd(this Selves&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves&...); template<typename Selves> void gd(this Selves&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void hd(this auto&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void jd(this auto&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + + template<typename ...Selves> + void kd(this Selves&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S2 { template<typename Selves> - void f(this Selves&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves&&...) {} template<typename Selves> void g(this Selves&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } @@ -72,19 +84,25 @@ struct S2 { void h(this auto&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } void j(this auto&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename ...Selves> + void k(this Selves&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename Selves> - void fd(this Selves&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves&&...); template<typename Selves> void gd(this Selves&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void hd(this auto&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void jd(this auto&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + + template<typename ...Selves> + void kd(this Selves&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S3 { template<typename Selves> - void f(this Selves const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves const&...) {} template<typename Selves> void g(this Selves const&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } @@ -92,19 +110,25 @@ struct S3 { void h(this auto const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } void j(this auto const&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename ...Selves> + void k(this Selves const&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename Selves> - void fd(this Selves const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves const&...); template<typename Selves> void gd(this Selves const&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void hd(this auto const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void jd(this auto const&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + + template<typename ...Selves> + void kd(this Selves const&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; struct S4 { template<typename Selves> - void f(this Selves const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void f(this Selves const&&...) {} template<typename Selves> void g(this Selves const&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } @@ -112,13 +136,18 @@ struct S4 { void h(this auto const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } void j(this auto const&&... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename ...Selves> + void k(this Selves const&&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } + template<typename Selves> - void fd(this Selves const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } + void fd(this Selves const&&...); template<typename Selves> void gd(this Selves const&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void hd(this auto const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } void jd(this auto const&&... selves); // { dg-error "an explicit object parameter cannot be a function parameter pack" } -}; + template<typename ...Selves> + void kd(this Selves const&&...); // { dg-error "an explicit object parameter cannot be a function parameter pack" } +}; Jakub