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