https://gcc.gnu.org/g:19505078164bf791d661d87d1069e5f50cd33417
commit r16-8396-g19505078164bf791d661d87d1069e5f50cd33417 Author: Jakub Jelinek <[email protected]> Date: Wed Apr 1 20:13:23 2026 +0200 c++: Implement CWG3124 - Disallow annotations on block-scope externs and non-unique friend declarations This issue says it is invalid to declare annotations on local externs or non-defining friends and their arguments (if any). 2026-04-01 Jakub Jelinek <[email protected]> * name-lookup.cc (push_local_extern_decl_alias): Diagnose annotations on local externs and their arguments. * decl.cc (grokdeclarator): Diagnose annotations on non-defining friends and their arguments. * g++.dg/reflect/annotations17.C: New test. Diff: --- gcc/cp/decl.cc | 21 +++++++++++ gcc/cp/name-lookup.cc | 16 +++++++++ gcc/testsuite/g++.dg/reflect/annotations17.C | 53 ++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 74099c34348a..8409752aa0c8 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -16618,6 +16618,27 @@ grokdeclarator (const cp_declarator *declarator, if (friendp) { + if (flag_reflection && !funcdef_flag && decl) + { + if (attrlist + && lookup_attribute ("internal ", "annotation ", + *attrlist)) + { + /* Remove the annotations to avoid spurious warning + below. */ + *attrlist = remove_attribute ("internal ", "annotation ", + *attrlist); + error_at (id_loc, "annotation applied to non-defining " + "friend declaration %qD", decl); + } + for (tree arg = DECL_ARGUMENTS (decl); + arg; arg = DECL_CHAIN (arg)) + if (lookup_attribute ("internal ", "annotation ", + DECL_ATTRIBUTES (arg))) + error_at (DECL_SOURCE_LOCATION (arg), + "annotation applied to parameter %qD of " + "non-defining friend declaration", arg); + } /* Packages tend to use GNU attributes on friends, so we only warn for standard attributes. */ if (attrlist diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 13aafab4e685..c0f48b5496dc 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -3690,6 +3690,22 @@ set_decl_context_in_fn (tree ctx, tree decl) void push_local_extern_decl_alias (tree decl) { + if (flag_reflection) + { + if (lookup_attribute ("internal ", "annotation ", + DECL_ATTRIBUTES (decl))) + error_at (DECL_SOURCE_LOCATION (decl), + "annotation applied to block scope extern %qD", + decl); + if (TREE_CODE (decl) == FUNCTION_DECL) + for (tree arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg)) + if (lookup_attribute ("internal ", "annotation ", + DECL_ATTRIBUTES (arg))) + error_at (DECL_SOURCE_LOCATION (arg), + "annotation applied to parameter %qD of block scope " + "extern", arg); + } + if (dependent_type_p (TREE_TYPE (decl)) || (processing_template_decl && VAR_P (decl) diff --git a/gcc/testsuite/g++.dg/reflect/annotations17.C b/gcc/testsuite/g++.dg/reflect/annotations17.C new file mode 100644 index 000000000000..caecec207491 --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/annotations17.C @@ -0,0 +1,53 @@ +// CWG3124 - Disallow annotations on block-scope externs and non-unique friend declarations +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +void +foo () +{ + [[=1]] extern int a; // { dg-error "annotation applied to block scope extern 'a'" } + extern int b [[=2]]; // { dg-error "annotation applied to block scope extern 'b'" } + [[=3]] extern int bar (int); // { dg-error "annotation applied to block scope extern 'int bar\\\(int\\\)'" } + extern int baz [[=4]] (int); // { dg-error "annotation applied to block scope extern 'int baz\\\(int\\\)'" } + extern int qux (int a[[=5]]); // { dg-error "annotation applied to parameter 'a' of block scope extern" } +} + +class S +{ + int s; + S (); + [[=6]] friend void corge (); // { dg-error "annotation applied to non-defining friend declaration 'void corge\\\(\\\)'" } + friend void garply ([[=7]] int a); // { dg-error "annotation applied to parameter 'a' of non-defining friend declaration" } + [[=8]] friend void fred () {} + friend void xyzzy (int a[[=9]]) {} + template <typename T> + [[=10]] friend void quux (); // { dg-error "annotation applied to non-defining friend declaration 'void quux\\\(\\\)'" } + template <typename T> + friend void grault ([[=11]] int a); // { dg-error "annotation applied to parameter 'a' of non-defining friend declaration" } + template <typename T> + [[=12]] friend void waldo () {} + template <typename T> + friend void thud (int a[[=13]]) {} +}; + +template <typename T> +class U +{ + int u; + [[=14]] friend void corge (long); // { dg-error "annotation applied to non-defining friend declaration 'void corge\\\(long int\\\)'" } + friend void garply (long, [[=16]] int a); // { dg-error "annotation applied to parameter 'a' of non-defining friend declaration" } + [[=16]] friend void fred (long) {} + friend void xyzzy (long, int a[[=17]]) {} + template <typename V> + [[=18]] friend void quux (long); // { dg-error "annotation applied to non-defining friend declaration 'void quux\\\(long int\\\)'" } + template <typename V> + friend void grault (long, [[=19]] int a); // { dg-error "annotation applied to parameter 'a' of non-defining friend declaration" } + template <typename V> + [[=20]] friend void waldo (long) {} + template <typename V> + friend void thud (long, int a[[=21]]) {} +public: + U () : u (42) {} +}; + +U <int> u;
