aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/aarch64/aarch64.c53
2 files changed, 55 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 69f07c4..71c480a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2020-04-23 Matthew Malcomson <matthew.malcomson@arm.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/94383
+ * config/aarch64/aarch64.c (aapcs_vfp_sub_candidate): Account for C++17
+ empty base class artificial fields.
+ (aarch64_vfp_is_call_or_return_candidate): Warn when ABI PCS decision is
+ different after this fix.
+
2020-04-23 Jakub Jelinek <jakub@redhat.com>
PR target/94707
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index f728ac5..a81b0b2 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -16442,9 +16442,19 @@ aarch64_member_type_forces_blk (const_tree field_or_array, machine_mode mode)
If *MODEP is VOIDmode, then set it to the first valid floating point
type. If a non-floating point type is found, or if a floating point
type that doesn't match a non-VOIDmode *MODEP is found, then return -1,
- otherwise return the count in the sub-tree. */
+ otherwise return the count in the sub-tree.
+
+ The AVOID_CXX17_EMPTY_BASE argument is to allow the caller to check whether
+ this function has changed its behavior after the fix for PR94384 -- this fix
+ is to avoid artificial fields in empty base classes.
+ When called with this argument as a NULL pointer this function does not
+ avoid the artificial fields -- this is useful to check whether the function
+ returns something different after the fix.
+ When called pointing at a value, this function avoids such artificial fields
+ and sets the value to TRUE when one of these fields has been set. */
static int
-aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep)
+aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep,
+ bool *avoid_cxx17_empty_base)
{
machine_mode mode;
HOST_WIDE_INT size;
@@ -16520,7 +16530,8 @@ aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep)
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return -1;
- count = aapcs_vfp_sub_candidate (TREE_TYPE (type), modep);
+ count = aapcs_vfp_sub_candidate (TREE_TYPE (type), modep,
+ avoid_cxx17_empty_base);
if (count == -1
|| !index
|| !TYPE_MAX_VALUE (index)
@@ -16558,7 +16569,18 @@ aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep)
if (TREE_CODE (field) != FIELD_DECL)
continue;
- sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
+ /* Ignore C++17 empty base fields, while their type indicates
+ they do contain padding, they have zero size and thus don't
+ contain any padding. */
+ if (cxx17_empty_base_field_p (field)
+ && avoid_cxx17_empty_base)
+ {
+ *avoid_cxx17_empty_base = true;
+ continue;
+ }
+
+ sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep,
+ avoid_cxx17_empty_base);
if (sub_count < 0)
return -1;
count += sub_count;
@@ -16591,7 +16613,8 @@ aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep)
if (TREE_CODE (field) != FIELD_DECL)
continue;
- sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
+ sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep,
+ avoid_cxx17_empty_base);
if (sub_count < 0)
return -1;
count = count > sub_count ? count : sub_count;
@@ -16718,10 +16741,26 @@ aarch64_vfp_is_call_or_return_candidate (machine_mode mode,
}
else if (type && composite_p)
{
- int ag_count = aapcs_vfp_sub_candidate (type, &new_mode);
-
+ bool avoided = false;
+ int ag_count = aapcs_vfp_sub_candidate (type, &new_mode, &avoided);
if (ag_count > 0 && ag_count <= HA_MAX_NUM_FLDS)
{
+ static unsigned last_reported_type_uid;
+ unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (type));
+ int alt;
+ if (warn_psabi
+ && avoided
+ && uid != last_reported_type_uid
+ && ((alt = aapcs_vfp_sub_candidate (type, &new_mode, NULL))
+ != ag_count))
+ {
+ gcc_assert (alt == -1);
+ last_reported_type_uid = uid;
+ 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);
+ }
+
if (is_ha != NULL) *is_ha = true;
*count = ag_count;
}