https://gcc.gnu.org/g:3d84356bcbeefabf45420fe1299e29a079a96adb
commit r16-6723-g3d84356bcbeefabf45420fe1299e29a079a96adb Author: Jason Merrill <[email protected]> Date: Fri Jan 9 14:01:26 2026 +0800 c++: more gnu_inline linkage adjustment Since r16-6477 we allow a gnu_inline to be a key method, because it is only emitted in one place. It occurs to me that we should make the same adjustment to other places that check DECL_DECLARED_INLINE_P to decide if a function has inline/vague/comdat linkage. PR libstdc++/123326 gcc/cp/ChangeLog: * cp-tree.h (DECL_NONGNU_INLINE_P): New. * decl.cc (duplicate_decls, start_decl): Check it. * decl2.cc (vague_linkage_p, import_export_class): Likewise. (vtables_uniquely_emitted, import_export_decl): Likewise. * class.cc (determine_key_method): Check it instead of lookup_attribute. Diff: --- gcc/cp/cp-tree.h | 6 ++++++ gcc/cp/class.cc | 11 +++++------ gcc/cp/decl.cc | 4 ++-- gcc/cp/decl2.cc | 8 ++++---- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b8470fc256ce..1a58ea0562ae 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3848,6 +3848,12 @@ struct GTY(()) lang_decl { #define DECL_PENDING_INLINE_INFO(NODE) \ (LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info) +/* True if NODE is a non-gnu_inline inline function; gnu_inline overrides the + usual vague linkage effects of inline. */ +#define DECL_NONGNU_INLINE_P(NODE) \ + (DECL_DECLARED_INLINE_P (NODE) \ + && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (NODE))) + /* Nonzero for TYPE_DECL means that it was written 'using name = type'. */ #define TYPE_DECL_ALIAS_P(NODE) \ DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE)) diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index a6a7c88c3ddd..adffd35123c6 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -7472,12 +7472,11 @@ determine_key_method (tree type) for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method)) if (TREE_CODE (method) == FUNCTION_DECL && DECL_VINDEX (method) != NULL_TREE - && (! DECL_DECLARED_INLINE_P (method) - /* [[gnu::gnu_inline]] virtual inline/constexpr methods will - have out of line bodies emitted in some other TU and so - those can be key methods and vtable emitted in the TU with - the actual out of line definition. */ - || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (method))) + /* [[gnu::gnu_inline]] virtual inline/constexpr methods will + have out of line bodies emitted in some other TU and so + those can be key methods and vtable emitted in the TU with + the actual out of line definition. */ + && ! DECL_NONGNU_INLINE_P (method) && ! DECL_PURE_VIRTUAL_P (method)) { SET_CLASSTYPE_KEY_METHOD (type, method); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index a2a14c4c008e..567aa7abe42a 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -3087,7 +3087,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) SET_DECL_TEMPLATE_SPECIALIZATION (olddecl); DECL_COMDAT (newdecl) = (TREE_PUBLIC (newdecl) - && DECL_DECLARED_INLINE_P (newdecl)); + && DECL_NONGNU_INLINE_P (newdecl)); /* Don't propagate visibility from the template to the specialization here. We'll do that in determine_visibility if @@ -6636,7 +6636,7 @@ start_decl (const cp_declarator *declarator, SET_DECL_TEMPLATE_SPECIALIZATION (decl); if (TREE_CODE (decl) == FUNCTION_DECL) DECL_COMDAT (decl) = (TREE_PUBLIC (decl) - && DECL_DECLARED_INLINE_P (decl)); + && DECL_NONGNU_INLINE_P (decl)); else DECL_COMDAT (decl) = false; diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index e807eab1b8a1..af2b921268d6 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -2511,7 +2511,7 @@ vague_linkage_p (tree decl) DECL_COMDAT. */ if (DECL_COMDAT (decl) || (TREE_CODE (decl) == FUNCTION_DECL - && DECL_DECLARED_INLINE_P (decl)) + && DECL_NONGNU_INLINE_P (decl)) || (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLOID_INSTANTIATION (decl)) || (VAR_P (decl) && DECL_INLINE_VAR_P (decl))) @@ -2581,7 +2581,7 @@ import_export_class (tree ctype) translation units. If we were to emit the vtable in each translation unit containing a definition, we would get multiple definition errors at link-time. */ - if (method && (flag_weak || ! DECL_DECLARED_INLINE_P (method))) + if (method && (flag_weak || ! DECL_NONGNU_INLINE_P (method))) import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1); } } @@ -3532,7 +3532,7 @@ vtables_uniquely_emitted (tree ctype) object for the TU containing the definition of the key function. This is unique if the key function is not inline. */ tree key_method = CLASSTYPE_KEY_METHOD (ctype); - if (key_method && !DECL_DECLARED_INLINE_P (key_method)) + if (key_method && !DECL_NONGNU_INLINE_P (key_method)) return true; /* Otherwise, the tables are emitted in every object that references @@ -3730,7 +3730,7 @@ import_export_decl (tree decl) } else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (decl)) { - if (!DECL_DECLARED_INLINE_P (decl)) + if (!DECL_NONGNU_INLINE_P (decl)) { tree ctype = DECL_CONTEXT (decl); import_export_class (ctype);
