Hi, The following code is accepted by GCC 10.2: struct S { [[deprecated]] friend void f(); }; No errors and no warnings are generated under -Wall -Wextra -pedantic. The code is however ill-formed: an attribute cannot appear on a friend declaration which isn't also a definition: https://eel.is/c++draft/dcl.attr#grammar-5.sentence-3 If an attribute-specifier-seq appertains to a friend declaration ([class.friend]), that declaration shall be a definition. For comparison, Clang rejects this, and MSVC accepts it (without warnings).
Mine for GCC 12.
Current test: class X { }; template<typename T1, typename T2> void foo (T1, T2); struct S { [[deprecated]] friend void f(); // error [[deprecated]] friend void f2() { } friend void f3 [[deprecated]] (); // error friend void f4 [[deprecated]] () { } [[deprecated]] friend void; // error [[deprecated]] friend X; // error [[deprecated]] friend class N; // error friend class [[deprecated]] N2; // error [[deprecated]] friend void foo<>(int, int); // error // FIXME: When PR100339 is resolved. //[[deprecated]] friend void ::foo(int, int); // error }; template<typename T> class node { }; template<typename T> struct A { [[deprecated]] friend T; // error [[deprecated]] friend class node<T>; // we warn template<typename> [[deprecated]] friend class A; // we warn template<typename> [[deprecated]] friend void bar () { } // OK template<typename> [[deprecated]] friend void baz (); // error };
The master branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:149061188c7c6ddf27663c8c00b7574fc8d0fd23 commit r12-786-g149061188c7c6ddf27663c8c00b7574fc8d0fd23 Author: Marek Polacek <polacek@redhat.com> Date: Thu Apr 29 21:38:14 2021 -0400 c++: Check attributes on friend declarations [PR99032] This patch implements [dcl.attr.grammar]/5: "If an attribute-specifier-seq appertains to a friend declaration ([class.friend]), that declaration shall be a definition." This restriction applies to C++11-style attributes as well as GNU attributes with the exception that we allow GNU attributes that require a type, such as vector_size to continue accepting code as in attrib63.C. There are various forms of friend declarations, we have friend templates, C++11 extended friend declarations, and so on. In some cases we already ignore the attribute and warn that it was ignored. But certain cases weren't diagnosed, and with this patch we'll give a hard error. I tried hard not to emit both a warning and error and I think it worked out. Jason provided the cp_parser_decl_specifier_seq hunk to detect using standard attributes in the middle of decl-specifiers, which is invalid. Co-authored-by: Jason Merrill <jason@redhat.com> gcc/cp/ChangeLog: PR c++/99032 * cp-tree.h (any_non_type_attribute_p): Declare. * decl.c (grokdeclarator): Diagnose when an attribute appertains to a friend declaration that is not a definition. * decl2.c (any_non_type_attribute_p): New. * parser.c (cp_parser_decl_specifier_seq): Diagnose standard attributes in the middle of decl-specifiers. (cp_parser_elaborated_type_specifier): Diagnose when an attribute appertains to a friend declaration that is not a definition. (cp_parser_member_declaration): Likewise. gcc/testsuite/ChangeLog: PR c++/99032 * g++.dg/cpp0x/friend7.C: New test. * g++.dg/cpp0x/gen-attrs-4.C: Add dg-error. * g++.dg/cpp0x/gen-attrs-39-1.C: Likewise. * g++.dg/cpp0x/gen-attrs-74.C: New test. * g++.dg/ext/attrib63.C: New test.
Fixed in GCC 12.