Message ID | Zc8k0y5zsJQhZ+2k@tucnak |
---|---|
State | New |
Headers | show |
Series | c++: Fix up parameter pack diagnostics on xobj vs. varargs functions [PR113802] | expand |
On 2/16/24 04:03, Jakub Jelinek wrote: > Hi! > > The simple presence of ellipsis as next token after the parameter > declaration doesn't imply it is a parameter pack, it sometimes is, e.g. > if its type is a pack, but sometimes is not and in that case it acts > the same as if the next tokens were , ... instead of just ... > The xobj param cannot be a function parameter pack though treats both > the declarator->parameter_pack_p and token->type == CPP_ELLIPSIS as > sufficient conditions for the error. The conditions for CPP_ELLIPSIS > are done a little bit later in the same function and complex enough that > IMHO shouldn't be repeated, on the other side for the > declarator->parameter_pack_p case we clear that flag for xobj params > for error recovery reasons. > In order to avoid diagnosing this in two spots, one at the current spot > for declarator->parameter_pack_p and one for the ellipsis case after > we decide if it is parameter pack or varargs, the following patch instead > just sets a boolean flag whether we should emit this diagnostics, does it > early for declarator->parameter_pack_p case and clears the parameter_pack_p > flag in that case like the older patch did, and for the ellipsis case > sets the flag later, then emits the diagnostics. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2024-02-16 Jakub Jelinek <jakub@redhat.com> > > PR c++/113802 > * parser.cc (cp_parser_parameter_declaration): Don't emit > PR113307 diagnostics too early, instead for the > declarator->parameter_pack_p case just set a flag it should be emitted > later. Set that flag also when consuming following ellipsis as part > of a parameter pack and diagnose either afterwards. 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-14 14:26:19.000000000 +0100 > +++ gcc/cp/parser.cc 2024-02-15 11:58:27.033618967 +0100 > @@ -25727,17 +25727,10 @@ cp_parser_parameter_declaration (cp_pars > bool const xobj_param_p > = decl_spec_seq_has_spec_p (&decl_specifiers, ds_this); > > - if (xobj_param_p > - && ((declarator && declarator->parameter_pack_p) > - || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))) > + bool diag_xobj_parameter_pack = false; > + if (xobj_param_p && (declarator && declarator->parameter_pack_p)) > { > - 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"); > + diag_xobj_parameter_pack = true; > /* Suppress errors that occur down the line. */ > if (declarator) > declarator->parameter_pack_p = false; > @@ -25755,9 +25748,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)) > @@ -25773,6 +25767,8 @@ cp_parser_parameter_declaration (cp_pars > || (!type && template_parm_p)) > && declarator_can_be_parameter_pack (declarator)) > { > + if (xobj_param_p) > + diag_xobj_parameter_pack = true; > /* Consume the `...'. */ > cp_lexer_consume_token (parser->lexer); > maybe_warn_variadic_templates (); > @@ -25787,6 +25783,17 @@ cp_parser_parameter_declaration (cp_pars > } > } > > + if (diag_xobj_parameter_pack) Can we move all the xobj handling down here (where we can trust declarator->parameter_pack_p) instead of adding a new variable? > + { > + 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"); > + } > + > /* 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-01-17 10:34:49.812597960 +0100 > +++ gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C 2024-02-15 12:14:29.994356800 +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 >
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 <jakub@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
On Fri, Feb 16, 2024 at 10:20:26PM +0100, Jakub Jelinek wrote: > 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 '...': And the reason for those is that e.g. on the reduced struct S0 { void j(this auto... selves) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; with the first posted patch we first do: if (xobj_param_p && (declarator && declarator->parameter_pack_p)) and clear declarator->parameter_pack_p there. Then comes if (parser->implicit_template_parms && ((token->type == CPP_ELLIPSIS && declarator_can_be_parameter_pack (declarator)) || (declarator && declarator->parameter_pack_p))) which is true only with the second patch and not the first. Adding if (parser->implicit_template_parms && ((token->type == CPP_ELLIPSIS && declarator_can_be_parameter_pack (declarator)) - || (declarator && declarator->parameter_pack_p))) + || (declarator && declarator->parameter_pack_p && !xobj_param_p))) { int latest_template_parm_idx = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS (current_template_parms)); fixes some of the excess errors, but not all of them, e.g. on struct S1 { void h(this auto&...) {} // { dg-error "an explicit object parameter cannot be a function parameter pack" } }; it still remains. The problem in there is that apparently we need declarator->parameter_pack_p cleared on the xobj diagnostics iff it was previously set before the CPP_ELLIPSIS handling above it, but not if it was set in that handling. I'm afraid I have no idea why though. The following patch works. 2024-02-16 Jakub Jelinek <jakub@redhat.com> PR c++/113802 * parser.cc (cp_parser_parameter_declaration): Move the xobj_param_p pack diagnostics after ellipsis handling, but only clear declarator->parameter_pack_p for it if it was set before CPP_ELLIPSIS handling. Ignore declarator->parameter_pack_p if xobj_param_p. 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:42:38.393896067 +0100 @@ -25734,39 +25734,25 @@ 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. */ if (parser->implicit_template_parms && ((token->type == CPP_ELLIPSIS && declarator_can_be_parameter_pack (declarator)) - || (declarator && declarator->parameter_pack_p))) + || (declarator && declarator->parameter_pack_p && !xobj_param_p))) { int latest_template_parm_idx = TREE_VEC_LENGTH (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); } + bool prev_parameter_pack_p = declarator && declarator->parameter_pack_p; if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { tree type = decl_specifiers.type; @@ -25794,6 +25780,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 = !prev_parameter_pack_p; + } + /* 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
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
On 2/16/24 17:15, Jakub Jelinek wrote: > 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. Let's go with this one. OK. > 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 >
--- gcc/cp/parser.cc.jj 2024-02-14 14:26:19.000000000 +0100 +++ gcc/cp/parser.cc 2024-02-15 11:58:27.033618967 +0100 @@ -25727,17 +25727,10 @@ cp_parser_parameter_declaration (cp_pars bool const xobj_param_p = decl_spec_seq_has_spec_p (&decl_specifiers, ds_this); - if (xobj_param_p - && ((declarator && declarator->parameter_pack_p) - || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))) + bool diag_xobj_parameter_pack = false; + if (xobj_param_p && (declarator && declarator->parameter_pack_p)) { - 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"); + diag_xobj_parameter_pack = true; /* Suppress errors that occur down the line. */ if (declarator) declarator->parameter_pack_p = false; @@ -25755,9 +25748,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)) @@ -25773,6 +25767,8 @@ cp_parser_parameter_declaration (cp_pars || (!type && template_parm_p)) && declarator_can_be_parameter_pack (declarator)) { + if (xobj_param_p) + diag_xobj_parameter_pack = true; /* Consume the `...'. */ cp_lexer_consume_token (parser->lexer); maybe_warn_variadic_templates (); @@ -25787,6 +25783,17 @@ cp_parser_parameter_declaration (cp_pars } } + if (diag_xobj_parameter_pack) + { + 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"); + } + /* 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-01-17 10:34:49.812597960 +0100 +++ gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C 2024-02-15 12:14:29.994356800 +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" } +};