]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: more gnu_inline linkage adjustment
authorJason Merrill <jason@redhat.com>
Fri, 9 Jan 2026 06:01:26 +0000 (14:01 +0800)
committerJason Merrill <jason@redhat.com>
Mon, 12 Jan 2026 16:18:35 +0000 (00:18 +0800)
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.

gcc/cp/class.cc
gcc/cp/cp-tree.h
gcc/cp/decl.cc
gcc/cp/decl2.cc

index a6a7c88c3ddd7696a6c490742dd46f9a09a27ccb..adffd35123c646282cc2b0f985260e09a61d2446 100644 (file)
@@ -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);
index b8470fc256ce1e28d8b4674ba5a5eb27c2ae6899..1a58ea0562ae1fb0afd2e79b3ad146b33fa4c396 100644 (file)
@@ -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))
index a2a14c4c008e2211bf8ed3bb2a72480436efaaa5..567aa7abe42a99216731bcb2232030fd7cf75208 100644 (file)
@@ -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;
 
index e807eab1b8a15d109ca0a9a87af360f8b0be12cc..af2b921268d6698a1b13a286f963c38ee23e0c53 100644 (file)
@@ -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);