On 3/13/25 3:16 PM, Jakub Jelinek wrote:
On Thu, Mar 13, 2025 at 01:45:43PM -0400, Jason Merrill wrote:
On 3/13/25 11:27 AM, Jakub Jelinek wrote:
Parsing a jump-statement under cp_parser_expression_statement just because
it happens to start with __attribute is pretty strange.
It is true that it is pretty strange, but that is where we handle the
empty declarations with GNU attributes (or shall those be called attribute
declarations) as well. Or are empty statements with GNU attribute
expression-statement with no expression?
Yes, empty statements are technically expression-statements.
How about changing cp_parser_std_attribute_spec_seq in cp_parser_statement
to cp_parser_attributes_opt?
I'd be afraid that would be quite significant change of behavior everywhere,
something that C doesn't allow (like mixing std and GNU attributes in any
orders or [[]] __attribute__(()) [[]][[]] __attribute__(())
expression-statement). Or it would allow __attribute__(()) on while, do,
for, if, switch, ..., again something that wasn't accepted before.
Do you think those changes are undesirable? We've previously had to fix
cases where we were failing to support mixing of std and GNU attributes.
In any case, calling cp_parser_jump_expression from cp_parser_statement
directly rather than from cp_parser_expression_statement is easily possible
just by doing
else if (cp_next_tokens_can_be_gnu_attribute_p (parser))
{
unsigned int n = cp_parser_skip_gnu_attributes_opt (parser, 1);
if (cp_lexer_nth_token_is_keyword (parser->lexer, n, RID_RETURN))
{
tree attr = cp_parser_gnu_attributes_opt (parser);
for (tree a = lookup_attribute ("musttail", attr);
a; a = lookup_attribute ("musttail", TREE_CHAIN (a)))
if (TREE_VALUE (a))
error ("%qs attribute does not take any arguments",
"musttail");
statement = cp_parser_jump_statement (parser, attr);
if (attr != NULL_TREE && any_nonignored_attribute_p (attr))
warning_at (loc, OPT_Wattributes,
"attributes at the beginning of statement are "
"ignored");
return statement;
}
}
after
else if (token->type == CPP_EOF)
{
cp_parser_error (parser, "expected statement");
return;
}
Or the GNU attributes on empty statement stuff could move there as well.
Yes, it seems desirable to move all the attribute handling out of
cp_parser_expression_statement; in the grammar, the attributes aren't
part of the expression-statement, and it's odd to handle fallthrough in
both places.
Jason