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
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);
&& ((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#zero_width_bitfields";
gcc_assert (alt == -1);
last_reported_type_uid = uid;
/* Use TYPE_MAIN_VARIANT to strip any redundant const
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);
}
*count = ag_count;
}
--- /dev/null
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_hard_vfp_ok } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp26.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, R0)
+ ARG(struct z, a, S0)
+ LAST_ARG(struct z, b, S2)
+#endif