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);

Reply via email to