]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Allow standard attributes after closing square bracket in new-type-id [PR110345]
authorJakub Jelinek <jakub@redhat.com>
Fri, 30 Aug 2024 07:40:34 +0000 (09:40 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 30 Aug 2024 07:40:34 +0000 (09:40 +0200)
For C++ 26 P2552R3 I went through all the spots (except modules) where
attribute-specifier-seq appears in the grammar and tried to construct
a testcase in all those spots, for now for [[deprecated]] attribute.

The first thing I found is that we aren't parsing standard attributes in
noptr-new-declarator - https://eel.is/c++draft/expr.new#1

The following patch parses it there, for the non-outermost arrays
applies normally the attributes to the array type, for the outermost
where we just set *nelts and don't really build an array type just
warns that we ignore those attributes (or, do you think we should
just build an array type in that case and just take its element type?).

2024-08-30  Jakub Jelinek  <jakub@redhat.com>

PR c++/110345
* parser.cc (make_array_declarator): Add STD_ATTRS argument, set
declarator->std_attributes to it.
(cp_parser_new_type_id): Warn on non-ignored std_attributes on the
array declarator which is being omitted.
(cp_parser_direct_new_declarator): Parse standard attributes after
closing square bracket, pass it to make_array_declarator.
(cp_parser_direct_declarator): Pass std_attrs to make_array_declarator
instead of setting declarator->std_attributes manually.

* g++.dg/cpp0x/gen-attrs-80.C: New test.
* g++.dg/cpp0x/gen-attrs-81.C: New test.

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

index 918072dbf637493895cceefb6f8fed16e2153657..632d3dc5ecf4fad92da24447939e4b4fa8718d32 100644 (file)
@@ -1689,7 +1689,7 @@ static cp_declarator *make_call_declarator
   (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier,
    tree, tree, tree, tree, tree, location_t);
 static cp_declarator *make_array_declarator
-  (cp_declarator *, tree);
+  (cp_declarator *, tree, tree);
 static cp_declarator *make_pointer_declarator
   (cp_cv_quals, cp_declarator *, tree);
 static cp_declarator *make_reference_declarator
@@ -1904,10 +1904,11 @@ make_call_declarator (cp_declarator *target,
 }
 
 /* Make a declarator for an array of BOUNDS elements, each of which is
-   defined by ELEMENT.  */
+   defined by ELEMENT.  STD_ATTRS contains attributes that appertain to
+   the array type.  */
 
 cp_declarator *
-make_array_declarator (cp_declarator *element, tree bounds)
+make_array_declarator (cp_declarator *element, tree bounds, tree std_attrs)
 {
   cp_declarator *declarator;
 
@@ -1923,6 +1924,8 @@ make_array_declarator (cp_declarator *element, tree bounds)
   else
     declarator->parameter_pack_p = false;
 
+  declarator->std_attributes = std_attrs;
+
   return declarator;
 }
 
@@ -9789,6 +9792,15 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts)
       if (*nelts == error_mark_node)
        *nelts = integer_one_node;
 
+      /* FIXME: Maybe build even the outermost array type and strip
+        it, to diagnose the attributes on it.  Problem is that VLAs aren't
+        pedantically allowed except for this case.  */
+      if (*nelts
+         && declarator->std_attributes
+         && any_nonignored_attribute_p (declarator->std_attributes))
+       warning (OPT_Wattributes, "attributes ignored on outermost array "
+                                 "type in new expression");
+
       if (*nelts == NULL_TREE)
        /* Leave [] in the declarator.  */;
       else if (outer_declarator)
@@ -9843,8 +9855,8 @@ cp_parser_new_declarator_opt (cp_parser* parser)
 /* Parse a direct-new-declarator.
 
    direct-new-declarator:
-     [ expression ]
-     direct-new-declarator [constant-expression]
+     [ expression ] attribute-specifier-seq [opt]
+     direct-new-declarator [constant-expression] attribute-specifier-seq [opt]
 
    */
 
@@ -9891,8 +9903,9 @@ cp_parser_direct_new_declarator (cp_parser* parser)
       /* Look for the closing `]'.  */
       cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 
+      tree attrs = cp_parser_std_attribute_spec_seq (parser);
       /* Add this bound to the declarator.  */
-      declarator = make_array_declarator (declarator, expression);
+      declarator = make_array_declarator (declarator, expression, attrs);
 
       /* If the next token is not a `[', then there are no more
         bounds.  */
@@ -24339,8 +24352,7 @@ cp_parser_direct_declarator (cp_parser* parser,
            }
 
          attrs = cp_parser_std_attribute_spec_seq (parser);
-         declarator = make_array_declarator (declarator, bounds);
-         declarator->std_attributes = attrs;
+         declarator = make_array_declarator (declarator, bounds, attrs);
        }
       else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
        {
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-80.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-80.C
new file mode 100644 (file)
index 0000000..edaa067
--- /dev/null
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+
+void
+foo (int n)
+{
+  auto a = new int [n] [[]];
+  auto b = new int [n] [[]] [42] [[]] [1] [[]];
+  delete[] b;
+  delete[] a;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-81.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-81.C
new file mode 100644 (file)
index 0000000..150c208
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+void
+foo (int n)
+{
+  auto a = new int [n] [[gnu::deprecated]];                            // { dg-warning "attributes ignored on outermost array type in new expression" }
+  auto b = new int [n] [[gnu::deprecated]] [42] [[]] [1] [[]];         // { dg-warning "attributes ignored on outermost array type in new expression" }
+  auto c = new int [n] [[]] [42] [[gnu::deprecated]] [1] [[gnu::deprecated]];
+  delete[] b;
+  delete[] a;
+}