aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-12-08 20:58:38 +0100
committerJakub Jelinek <jakub@redhat.com>2023-12-08 20:58:38 +0100
commit662a613dd381e327b90b42bb850cb393a01e7f7e (patch)
tree644d3c7a2898793da86820f6aecb6128422d9f51 /gcc
parent6ddaf06e375e1c15dcda338697ab6ea457e6f497 (diff)
downloadgcc-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.cc14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C9
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 ()
+{
+ [[]] [[]];
+}