diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-03-08 09:11:57 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2024-03-08 09:29:30 +0100 |
commit | 3ecc5071797c4ceb6da67a6c2b2527a046091de2 (patch) | |
tree | 51ba851ec7d90df49d807c68acb2a5f5a8956bf7 /gcc/cp/parser.cc | |
parent | 1329dacdc0fbe7d43550294fe8b0323a6dc5ce9e (diff) | |
download | gcc-3ecc5071797c4ceb6da67a6c2b2527a046091de2.zip gcc-3ecc5071797c4ceb6da67a6c2b2527a046091de2.tar.gz gcc-3ecc5071797c4ceb6da67a6c2b2527a046091de2.tar.bz2 |
c++: Fix up parameter pack diagnostics on xobj vs. varargs functions [PR113802]
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.
This patch just moves the diagnostics later (after the CPP_ELLIPSIS handling)
and changes the error recovery behavior by pretending the this specifier
didn't appear if an error is reported.
2024-03-08 Jakub Jelinek <jakub@redhat.com>
PR c++/113802
* parser.cc (cp_parser_parameter_declaration): Move the xobj_param_p
pack diagnostics after ellipsis handling and if an error is reported,
pretend this specifier didn't appear. 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. Expect extra diagnostics in error
recovery for g and gd member function templates.
Diffstat (limited to 'gcc/cp/parser.cc')
-rw-r--r-- | gcc/cp/parser.cc | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index e32acfc..bc3aa9d 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -25734,22 +25734,6 @@ cp_parser_parameter_declaration (cp_parser *parser, 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_parser *parser, (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_parser *parser, } } + 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; |