diff options
author | Jakub Jelinek <jakub@redhat.com> | 2023-12-08 20:58:38 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2023-12-08 20:58:38 +0100 |
commit | 662a613dd381e327b90b42bb850cb393a01e7f7e (patch) | |
tree | 644d3c7a2898793da86820f6aecb6128422d9f51 /gcc | |
parent | 6ddaf06e375e1c15dcda338697ab6ea457e6f497 (diff) | |
download | gcc-662a613dd381e327b90b42bb850cb393a01e7f7e.zip gcc-662a613dd381e327b90b42bb850cb393a01e7f7e.tar.gz gcc-662a613dd381e327b90b42bb850cb393a01e7f7e.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/parser.cc | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C | 9 |
2 files changed, 20 insertions, 3 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 6ec342c..ca91a50 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C new file mode 100644 index 0000000..6cdd65c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++11 } } + +[[]] [[]]; + +[[]] [[]] void +foo () +{ + [[]] [[]]; +} |