On 7/10/26 5:23 PM, Yuxuan Chen wrote:
From: Yuxuan Chen <[email protected]>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.
Pushed, thanks.
gcc/testsuite/ChangeLog: PR c++/125064 * g++.dg/cpp0x/attr-trivial_abi9.C: New test. Signed-off-by: Yuxuan Chen <[email protected]> --- Changes in v2: - Add missing Signed-off-by. gcc/cp/tree.cc | 22 ++++++++++--------- .../g++.dg/cpp0x/attr-trivial_abi9.C | 13 +++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/attr-trivial_abi9.C diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index e543cf14519..086960d1855 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -6086,6 +6086,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)) { @@ -6093,8 +6100,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; }@@ -6105,8 +6111,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; }@@ -6126,8 +6131,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; } } @@ -6147,8 +6151,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; } } @@ -6162,8 +6165,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 00000000000..a7b18457ae1 --- /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); }
