@@ -19355,6 +19355,7 @@ aarch64_member_type_forces_blk (const_tree field_or_array, machine_mode mode)
a HFA or HVA. */
const unsigned int WARN_PSABI_EMPTY_CXX17_BASE = 1U << 0;
const unsigned int WARN_PSABI_NO_UNIQUE_ADDRESS = 1U << 1;
+const unsigned int WARN_PSABI_ZERO_WIDTH_BITFIELD = 1U << 2;
/* Walk down the type tree of TYPE counting consecutive base elements.
If *MODEP is VOIDmode, then set it to the first valid floating point
@@ -19511,6 +19512,28 @@ aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep,
continue;
}
}
+ /* A zero-width bitfield may affect layout in some
+ circumstances, but adds no members. The determination
+ of whether or not a type is an HFA is performed after
+ layout is complete, so if the type still looks like an
+ HFA afterwards, it is still classed as one. This is
+ potentially an ABI break for the hard-float ABI. */
+ else if (DECL_BIT_FIELD (field)
+ && integer_zerop (DECL_SIZE (field)))
+ {
+ /* Prior to GCC-12 these fields were striped early,
+ hiding them from the back-end entirely and
+ resulting in the correct behaviour for argument
+ passing. Simulate that old behaviour without
+ generating a warning. */
+ if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
+ continue;
+ if (warn_psabi_flags)
+ {
+ *warn_psabi_flags |= WARN_PSABI_ZERO_WIDTH_BITFIELD;
+ continue;
+ }
+ }
sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep,
warn_psabi_flags);
@@ -19711,8 +19734,10 @@ aarch64_vfp_is_call_or_return_candidate (machine_mode mode,
&& ((alt = aapcs_vfp_sub_candidate (type, &new_mode, NULL))
!= ag_count))
{
- const char *url
+ const char *url10
= CHANGES_ROOT_URL "gcc-10/changes.html#empty_base";
+ const char *url12
+ = CHANGES_ROOT_URL "gcc-12/changes.html#empty_base";
gcc_assert (alt == -1);
last_reported_type_uid = uid;
/* Use TYPE_MAIN_VARIANT to strip any redundant const
@@ -19721,12 +19746,16 @@ aarch64_vfp_is_call_or_return_candidate (machine_mode mode,
inform (input_location, "parameter passing for argument of "
"type %qT with %<[[no_unique_address]]%> members "
"changed %{in GCC 10.1%}",
- TYPE_MAIN_VARIANT (type), url);
+ TYPE_MAIN_VARIANT (type), url10);
else if (warn_psabi_flags & WARN_PSABI_EMPTY_CXX17_BASE)
inform (input_location, "parameter passing for argument of "
"type %qT when C++17 is enabled changed to match "
"C++14 %{in GCC 10.1%}",
- TYPE_MAIN_VARIANT (type), url);
+ TYPE_MAIN_VARIANT (type), url10);
+ else if (warn_psabi_flags & WARN_PSABI_ZERO_WIDTH_BITFIELD)
+ inform (input_location, "parameter passing for argument of "
+ "type %qT changed %{in GCC 12.1%}",
+ TYPE_MAIN_VARIANT (type), url12);
}
if (is_ha != NULL) *is_ha = true;
new file mode 100644
@@ -0,0 +1,28 @@
+/* Test AAPCS64 layout for HFA with zero-sized bit-field. */
+
+/* { dg-do run { target aarch64*-*-* } } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "test_28.c"
+
+/* Anonymous bitfields do not add members; if they do not change the layout
+ then the end result may still be an HFA. */
+struct z
+{
+ float a;
+ int :0;
+ float b;
+};
+
+struct z a = { 5.0f, 6.0f };
+struct z b = { 9.0f, 10.0f };
+
+#define MYFUNCTYPE struct z
+
+#include "abitest.h"
+#else
+ ARG(int, 7, W0)
+ ARG(struct z, a, S0)
+ LAST_ARG(struct z, b, S2)
+#endif