aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.cc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-03-08 09:11:57 +0100
committerJakub Jelinek <jakub@redhat.com>2024-03-08 09:29:30 +0100
commit3ecc5071797c4ceb6da67a6c2b2527a046091de2 (patch)
tree51ba851ec7d90df49d807c68acb2a5f5a8956bf7 /gcc/cp/parser.cc
parent1329dacdc0fbe7d43550294fe8b0323a6dc5ce9e (diff)
downloadgcc-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.cc38
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;