]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix parsing [[]][[]];
authorJakub Jelinek <jakub@redhat.com>
Fri, 8 Dec 2023 19:58:38 +0000 (20:58 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 8 Dec 2023 19:58:38 +0000 (20:58 +0100)
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.

gcc/cp/parser.cc
gcc/testsuite/g++.dg/cpp0x/gen-attrs-79.C [new file with mode: 0644]

index 6ec342c08eda06aafe3f2ac003bb2851eb4f0c96..ca91a50f059e2b2af1546683ded41ee606a57960 100644 (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;
 
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 (file)
index 0000000..6cdd65c
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++11 } }
+
+[[]] [[]];
+
+[[]] [[]] void
+foo ()
+{
+  [[]] [[]];
+}