[Bug target/94707] [8/9/10 Regression] class with empty base passed incorrectly with -std=c++17 on powerpc64le
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Apr 22 10:12:12 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94707
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Updated incomplete patch on top of
https://gcc.gnu.org/pipermail/gcc-patches/2020-April/544276.html
I've handled one rs6000_discover_homogeneous_aggregate caller where it wasn't
that hard to figure out
how to report different decisions based on if GCC 7/8/9 with -std=c++17 would
make the aggregate
non-homogeneous because of the C++17 empty base artificial FIELD_DECL and we'd
return true because of that, while
in -std=c++14 and in patched GCC trunk we'd return false.
But I'm getting lost in all the other spots, figuring out if we made different
decisions is harder.
--- gcc/config/rs6000/rs6000-internal.h.jj 2020-03-20 09:11:36.229903622
+0100
+++ gcc/config/rs6000/rs6000-internal.h 2020-04-22 11:31:23.943522525 +0200
@@ -129,7 +129,8 @@ extern int rs6000_darwin64_struct_check_
extern bool rs6000_discover_homogeneous_aggregate (machine_mode mode,
const_tree type,
machine_mode *elt_mode,
- int *n_elts);
+ int *n_elts,
+ bool
*cxx17_empty_base_seen);
extern void rs6000_output_mi_thunk (FILE *file,
tree thunk_fndecl ATTRIBUTE_UNUSED,
HOST_WIDE_INT delta,
--- gcc/config/rs6000/rs6000-call.c.jj 2020-03-30 22:53:40.746640328 +0200
+++ gcc/config/rs6000/rs6000-call.c 2020-04-22 12:06:00.066843119 +0200
@@ -5528,7 +5528,8 @@ const struct altivec_builtin_types altiv
sub-tree. */
static int
-rs6000_aggregate_candidate (const_tree type, machine_mode *modep)
+rs6000_aggregate_candidate (const_tree type, machine_mode *modep,
+ bool *cxx17_empty_base_seen)
{
machine_mode mode;
HOST_WIDE_INT size;
@@ -5598,7 +5599,8 @@ rs6000_aggregate_candidate (const_tree t
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return -1;
- count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
+ count = rs6000_aggregate_candidate (TREE_TYPE (type), modep,
+ cxx17_empty_base_seen);
if (count == -1
|| !index
|| !TYPE_MAX_VALUE (index)
@@ -5636,7 +5638,15 @@ rs6000_aggregate_candidate (const_tree t
if (TREE_CODE (field) != FIELD_DECL)
continue;
- sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+ if (cxx17_empty_base_field_p (field))
+ {
+ if (cxx17_empty_base_seen)
+ *cxx17_empty_base_seen = true;
+ continue;
+ }
+
+ sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
+ cxx17_empty_base_seen);
if (sub_count < 0)
return -1;
count += sub_count;
@@ -5669,7 +5679,8 @@ rs6000_aggregate_candidate (const_tree t
if (TREE_CODE (field) != FIELD_DECL)
continue;
- sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+ sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
+ cxx17_empty_base_seen);
if (sub_count < 0)
return -1;
count = count > sub_count ? count : sub_count;
@@ -5700,7 +5711,8 @@ rs6000_aggregate_candidate (const_tree t
bool
rs6000_discover_homogeneous_aggregate (machine_mode mode, const_tree type,
machine_mode *elt_mode,
- int *n_elts)
+ int *n_elts,
+ bool *cxx17_empty_base_seen)
{
/* Note that we do not accept complex types at the top level as
homogeneous aggregates; these types are handled via the
@@ -5710,7 +5722,8 @@ rs6000_discover_homogeneous_aggregate (m
&& AGGREGATE_TYPE_P (type))
{
machine_mode field_mode = VOIDmode;
- int field_count = rs6000_aggregate_candidate (type, &field_mode);
+ int field_count = rs6000_aggregate_candidate (type, &field_mode,
+ cxx17_empty_base_seen);
if (field_count > 0)
{
@@ -5734,6 +5747,8 @@ rs6000_discover_homogeneous_aggregate (m
*elt_mode = mode;
if (n_elts)
*n_elts = 1;
+ if (cxx17_empty_base_seen)
+ *cxx17_empty_base_seen = false;
return false;
}
@@ -5790,9 +5805,14 @@ rs6000_return_in_memory (const_tree type
}
/* The ELFv2 ABI returns homogeneous VFP aggregates in registers */
+ bool cxx17_empty_base_seen = false;
if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (type), type,
- NULL, NULL))
- return false;
+ NULL, NULL,
+ &cxx17_empty_base_seen))
+ {
+ if (!cxx17_empty_base_seen || !warn_psabi)
+ return false;
+ }
/* The ELFv2 ABI returns aggregates up to 16B in registers */
if (DEFAULT_ABI == ABI_ELFv2 && AGGREGATE_TYPE_P (type)
@@ -5802,7 +5822,21 @@ rs6000_return_in_memory (const_tree type
if (AGGREGATE_TYPE_P (type)
&& (aix_struct_return
|| (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
- return true;
+ {
+ if (cxx17_empty_base_seen)
+ {
+ inform (input_location,
+ "prior to GCC 10, parameters of type %qT were passed "
+ "incorrectly for C++17", type);
+ return false;
+ }
+
+ return true;
+ }
+
+ /* The ELFv2 ABI returns homogeneous VFP aggregates in registers. */
+ if (cxx17_empty_base_seen)
+ return false;
/* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
modes only exist for GCC vector types if -maltivec. */
@@ -6141,7 +6175,8 @@ rs6000_function_arg_boundary (machine_mo
machine_mode elt_mode;
int n_elts;
- rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts,
+ NULL);
if (DEFAULT_ABI == ABI_V4
&& (GET_MODE_SIZE (mode) == 8
@@ -6409,7 +6444,8 @@ rs6000_function_arg_advance_1 (CUMULATIV
machine_mode elt_mode;
int n_elts;
- rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts,
+ NULL);
/* Only tick off an argument if we're not recursing. */
if (depth == 0)
@@ -6993,7 +7029,9 @@ rs6000_function_arg (cumulative_args_t c
return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
}
- rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+ bool cxx17_empty_base_seen = false;
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts,
+ &cxx17_empty_base_seen);
if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
{
@@ -7229,7 +7267,7 @@ rs6000_arg_partial_bytes (cumulative_arg
int n_elts;
rs6000_discover_homogeneous_aggregate (arg.mode, arg.type,
- &elt_mode, &n_elts);
+ &elt_mode, &n_elts, NULL);
if (DEFAULT_ABI == ABI_V4)
return 0;
--- gcc/config/rs6000/rs6000.c.jj 2020-04-17 08:49:49.040683868 +0200
+++ gcc/config/rs6000/rs6000.c 2020-04-22 12:06:34.988310057 +0200
@@ -22428,7 +22428,8 @@ rs6000_function_value (const_tree valtyp
mode = TYPE_MODE (valtype);
/* The ELFv2 ABI returns homogeneous VFP aggregates in registers. */
- if (rs6000_discover_homogeneous_aggregate (mode, valtype, &elt_mode,
&n_elts))
+ if (rs6000_discover_homogeneous_aggregate (mode, valtype, &elt_mode,
&n_elts,
+ NULL))
{
int first_reg, n_regs;
More information about the Gcc-bugs
mailing list