c++: Fix parsing [[]][[]];

When working on the previous patch I put [[]] [[]] asm (""); into a
testcase, but was surprised it wasn't parsed.
The problem is that when cp_parser_std_attribute_spec returns NULL, it
can mean 2 different things, one is that the next token(s) are neither
[[ nor alignas (in that case the caller should break from the loop),
or when we parsed something like [[]] - it was valid attribute specifier,
but didn't specify any attributes in it.

The following patch fixes that by using a magic value of void_list_node
for the case where the first tokens are neither [[ nor alignas and so
where cp_parser_std_attribute_spec_seq should stop iterating to differentiate
it from NULL_TREE which stands for some attribute specifier has been parsed,
but it didn't contain any (or any valid) attributes.

2023-12-08  Jakub Jelinek  <jakub@redhat.com>

	* parser.cc (cp_parser_std_attribute_spec): Return void_list_node
	rather than NULL_TREE if token is neither CPP_OPEN_SQUARE nor
	RID_ALIGNAS CPP_KEYWORD.
	(cp_parser_std_attribute_spec_seq): For attr_spec == void_list_node
	break, for attr_spec == NULL_TREE continue.

	* g++.dg/cpp0x/gen-attrs-79.C: New test.
This commit is contained in:
Jakub Jelinek 2023-12-08 20:58:38 +01:00
parent 6ddaf06e37
commit 662a613dd3
2 changed files with 20 additions and 3 deletions

View file

@ -30265,7 +30265,11 @@ void cp_parser_late_contract_condition (cp_parser *parser,
[ [ assert : contract-mode [opt] : conditional-expression ] ]
[ [ pre : contract-mode [opt] : conditional-expression ] ]
[ [ post : contract-mode [opt] identifier [opt] :
conditional-expression ] ] */
conditional-expression ] ]
Return void_list_node if the current token doesn't start an
attribute-specifier to differentiate from NULL_TREE returned e.g.
for [ [ ] ]. */
static tree
cp_parser_std_attribute_spec (cp_parser *parser)
@ -30345,7 +30349,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
if (token->type != CPP_KEYWORD
|| token->keyword != RID_ALIGNAS)
return NULL_TREE;
return void_list_node;
cp_lexer_consume_token (parser->lexer);
maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
@ -30418,8 +30422,12 @@ cp_parser_std_attribute_spec_seq (cp_parser *parser)
while (true)
{
tree attr_spec = cp_parser_std_attribute_spec (parser);
if (attr_spec == NULL_TREE)
if (attr_spec == void_list_node)
break;
/* Accept [[]][[]]; for which cp_parser_std_attribute_spec
returns NULL_TREE as there are no attributes. */
if (attr_spec == NULL_TREE)
continue;
if (attr_spec == error_mark_node)
return error_mark_node;

View file

@ -0,0 +1,9 @@
// { dg-do compile { target c++11 } }
[[]] [[]];
[[]] [[]] void
foo ()
{
[[]] [[]];
}