Hi! 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?). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-08-15 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. --- gcc/cp/parser.cc.jj 2024-08-15 14:56:29.007757215 +0200 +++ gcc/cp/parser.cc 2024-08-15 16:28:18.607692746 +0200 @@ -1689,7 +1689,7 @@ static cp_declarator *make_call_declarat (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 *tar } /* 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 *el else declarator->parameter_pack_p = false; + declarator->std_attributes = std_attrs; + return declarator; } @@ -9784,6 +9787,12 @@ cp_parser_new_type_id (cp_parser* parser if (*nelts == error_mark_node) *nelts = integer_one_node; + 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) @@ -9838,8 +9847,8 @@ cp_parser_new_declarator_opt (cp_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] */ @@ -9886,8 +9895,9 @@ cp_parser_direct_new_declarator (cp_pars /* 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. */ @@ -24330,8 +24340,7 @@ cp_parser_direct_declarator (cp_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) { --- gcc/testsuite/g++.dg/cpp0x/gen-attrs-80.C.jj 2024-08-15 15:27:00.297061501 +0200 +++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-80.C 2024-08-15 15:27:19.610822213 +0200 @@ -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; +} --- gcc/testsuite/g++.dg/cpp0x/gen-attrs-81.C.jj 2024-08-15 17:14:43.912228130 +0200 +++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-81.C 2024-08-15 17:19:01.738038053 +0200 @@ -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; +} Jakub