https://gcc.gnu.org/g:9004416d8dd9f4c94d72d921e31dadaf85134be5

commit r17-2371-g9004416d8dd9f4c94d72d921e31dadaf85134be5
Author: Yuxuan Chen <[email protected]>
Date:   Mon Jul 13 18:29:22 2026 -0400

    c++: Keep type variants consistent for trivial_abi [PR125064]
    
    Removing trivial_abi from only the main type can leave qualified variants
    with different attributes despite sharing a canonical type.  Remove the
    rejected attribute from all variants.
    
    gcc/cp/ChangeLog:
    
            PR c++/125064
            * tree.cc (validate_trivial_abi_attribute): Remove a rejected
            trivial_abi attribute from all variants.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/125064
            * g++.dg/cpp0x/attr-trivial_abi9.C: New test.
    
    Signed-off-by: Yuxuan Chen <[email protected]>

Diff:
---
 gcc/cp/tree.cc                                 | 22 ++++++++++++----------
 gcc/testsuite/g++.dg/cpp0x/attr-trivial_abi9.C | 13 +++++++++++++
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index e39a4a59b9af..22421afc4365 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -6184,6 +6184,13 @@ validate_trivial_abi_attribute (tree type)
 
   gcc_assert (COMPLETE_TYPE_P (type));
 
+  auto remove_trivial_abi_attribute = [type] {
+    for (tree variant = TYPE_MAIN_VARIANT (type); variant;
+        variant = TYPE_NEXT_VARIANT (variant))
+      TYPE_ATTRIBUTES (variant)
+       = remove_attribute ("trivial_abi", TYPE_ATTRIBUTES (variant));
+  };
+
   /* Check for virtual bases.  */
   if (CLASSTYPE_VBASECLASSES (type))
     {
@@ -6191,8 +6198,7 @@ validate_trivial_abi_attribute (tree type)
       if (warning (OPT_Wattributes, "%<trivial_abi%> cannot be applied to %qT",
                   type))
        inform (input_location, "has a virtual base");
-      TYPE_ATTRIBUTES (type)
-       = remove_attribute ("trivial_abi", TYPE_ATTRIBUTES (type));
+      remove_trivial_abi_attribute ();
       return;
     }
 
@@ -6203,8 +6209,7 @@ validate_trivial_abi_attribute (tree type)
       if (warning (OPT_Wattributes, "%<trivial_abi%> cannot be applied to %qT",
                   type))
        inform (input_location, "is polymorphic");
-      TYPE_ATTRIBUTES (type)
-       = remove_attribute ("trivial_abi", TYPE_ATTRIBUTES (type));
+      remove_trivial_abi_attribute ();
       return;
     }
 
@@ -6224,8 +6229,7 @@ validate_trivial_abi_attribute (tree type)
                           "%<trivial_abi%> cannot be applied to %qT", type))
                inform (input_location, "has a non-trivial base class %qT",
                        base_type);
-             TYPE_ATTRIBUTES (type)
-               = remove_attribute ("trivial_abi", TYPE_ATTRIBUTES (type));
+             remove_trivial_abi_attribute ();
              return;
            }
        }
@@ -6245,8 +6249,7 @@ validate_trivial_abi_attribute (tree type)
                           "%<trivial_abi%> cannot be applied to %qT", type))
                inform (input_location, "has a non-static data member "
                        "of non-trivial type %qT", field_type);
-             TYPE_ATTRIBUTES (type)
-               = remove_attribute ("trivial_abi", TYPE_ATTRIBUTES (type));
+             remove_trivial_abi_attribute ();
              return;
            }
        }
@@ -6260,8 +6263,7 @@ validate_trivial_abi_attribute (tree type)
                   type))
        inform (input_location,
                "copy constructors and move constructors are all deleted");
-      TYPE_ATTRIBUTES (type)
-       = remove_attribute ("trivial_abi", TYPE_ATTRIBUTES (type));
+      remove_trivial_abi_attribute ();
       return;
     }
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/attr-trivial_abi9.C 
b/gcc/testsuite/g++.dg/cpp0x/attr-trivial_abi9.C
new file mode 100644
index 000000000000..a7b18457ae1e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/attr-trivial_abi9.C
@@ -0,0 +1,13 @@
+// PR c++/125064
+// { dg-do compile { target c++17 } }
+
+struct A;
+class [[clang::trivial_abi]] B {
+  B(B &&);
+};
+void f(A);
+struct [[clang::trivial_abi]] A { // { dg-warning "cannot be applied" }
+  A(...);
+  B b;
+};
+void g() { f(1); }

Reply via email to