https://gcc.gnu.org/g:b748e2eed0df9e691a530a0b8faea9f673bdf2b5

commit r15-3315-gb748e2eed0df9e691a530a0b8faea9f673bdf2b5
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Aug 30 09:40:34 2024 +0200

    c++: Allow standard attributes after closing square bracket in new-type-id 
[PR110345]
    
    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  <ja...@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.

Diff:
---
 gcc/cp/parser.cc                          | 28 ++++++++++++++++++++--------
 gcc/testsuite/g++.dg/cpp0x/gen-attrs-80.C | 10 ++++++++++
 gcc/testsuite/g++.dg/cpp0x/gen-attrs-81.C | 11 +++++++++++
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 918072dbf637..632d3dc5ecf4 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -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
index 000000000000..edaa06766701
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-80.C
@@ -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
index 000000000000..150c2087e7a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-81.C
@@ -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;
+}

Reply via email to