https://gcc.gnu.org/g:1db5ca04da365ac57f7d788a85055edcf13da708
commit r15-3045-g1db5ca04da365ac57f7d788a85055edcf13da708 Author: Jakub Jelinek <ja...@redhat.com> Date: Tue Aug 20 22:15:03 2024 +0200 c++: Parse and ignore attributes on base specifiers [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. This is the third issue I found. https://eel.is/c++draft/class.derived#general-1 has attribute-specifier-seq at the start of base-specifier. The following patch parses it there and warns about those. 2024-08-20 Jakub Jelinek <ja...@redhat.com> PR c++/110345 * parser.cc (cp_parser_base_specifier): Parse standard attributes at the start and emit a warning if there are any non-ignored ones. * g++.dg/cpp0x/gen-attrs-83.C: New test. Diff: --- gcc/cp/parser.cc | 17 ++++++++++++----- gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C | 10 ++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index c43889803482..28ebf2beb60a 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -28995,11 +28995,12 @@ cp_parser_base_clause (cp_parser* parser) /* Parse a base-specifier. base-specifier: - :: [opt] nested-name-specifier [opt] class-name - virtual access-specifier [opt] :: [opt] nested-name-specifier - [opt] class-name - access-specifier virtual [opt] :: [opt] nested-name-specifier - [opt] class-name + attribute-specifier-seq [opt] :: [opt] nested-name-specifier [opt] + class-name + attribute-specifier-seq [opt] virtual access-specifier [opt] :: [opt] + nested-name-specifier [opt] class-name + attribute-specifier-seq [opt] access-specifier virtual [opt] :: [opt] + nested-name-specifier [opt] class-name Returns a TREE_LIST. The TREE_PURPOSE will be one of ACCESS_{DEFAULT,PUBLIC,PROTECTED,PRIVATE}_[VIRTUAL]_NODE to @@ -29017,6 +29018,12 @@ cp_parser_base_specifier (cp_parser* parser) bool class_scope_p, template_p; tree access = access_default_node; tree type; + location_t attrs_loc = cp_lexer_peek_token (parser->lexer)->location; + tree std_attrs = cp_parser_std_attribute_spec_seq (parser); + + if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs)) + warning_at (attrs_loc, OPT_Wattributes, + "attributes on base specifiers are ignored"); /* Process the optional `virtual' and `access-specifier'. */ while (!done) diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C new file mode 100644 index 000000000000..0ff1965d0ecf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++11 } } + +struct A {}; +struct B {}; +struct C {}; +struct D : [[]] [[]] A, + [[]] virtual public B, [[]] [[]] [[]] public virtual C {}; +struct E : [[gnu::deprecated]] A, // { dg-warning "attributes on base specifiers are ignored" } + [[gnu::deprecated]] virtual public B, // { dg-warning "attributes on base specifiers are ignored" } + [[gnu::deprecated]] public virtual C {}; // { dg-warning "attributes on base specifiers are ignored" }