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