On Tue, Apr 28, 2020 at 4:02 PM Jakub Jelinek <ja...@redhat.com> wrote: > > On Tue, Apr 28, 2020 at 05:42:00PM +0200, Jakub Jelinek wrote: > > Ok, below in the updated patch: > > This is what I've successfully bootstrapped/regtested on powerpc64le-linux > (last posted patch with the lto-common.c addition included). > Jason has already approved the non-rs6000 parts, so are those ok for trunk > too?
I bootstrapped the revised patch on AIX and do not see any of the struct-layout not new target testcase failures. The rs6000 parts of this patch are okay. Again, thanks for your diligent effort to track down and fix the fallout from the c++17 empty base class and same address changes. Thanks, David > > 2020-04-28 Jakub Jelinek <ja...@redhat.com> > > PR target/94707 > * tree-core.h (tree_decl_common): Note decl_flag_0 used for > DECL_FIELD_ABI_IGNORED. > * tree.h (DECL_FIELD_ABI_IGNORED): Define. > * calls.h (cxx17_empty_base_field_p): Change into a temporary > macro, check DECL_FIELD_ABI_IGNORED flag with no "no_unique_address" > attribute. > * calls.c (cxx17_empty_base_field_p): Remove. > * tree-streamer-out.c (pack_ts_decl_common_value_fields): Handle > DECL_FIELD_ABI_IGNORED. > * tree-streamer-in.c (unpack_ts_decl_common_value_fields): Likewise. > * lto-streamer-out.c (hash_tree): Likewise. > * config/rs6000/rs6000-call.c (rs6000_aggregate_candidate): Rename > cxx17_empty_base_seen to empty_base_seen, change type to int *, > adjust recursive calls, use DECL_FIELD_ABI_IGNORED instead of > cxx17_empty_base_field_p, if "no_unique_address" attribute is > present, propagate that to the caller too. > (rs6000_discover_homogeneous_aggregate): Adjust > rs6000_aggregate_candidate caller, emit different diagnostics > when c++17 empty base fields are present and when empty > [[no_unique_address]] fields are present. > * config/rs6000/rs6000.c (rs6000_special_round_type_align, > darwin_rs6000_special_round_type_align): Skip DECL_FIELD_ABI_IGNORED > fields. > > * class.c (build_base_field): Set DECL_FIELD_ABI_IGNORED on C++17 > empty > base artificial FIELD_DECLs. > (layout_class_type): Set DECL_FIELD_ABI_IGNORED on empty class > field_poverlapping_p FIELD_DECLs. > > * lto-common.c (compare_tree_sccs_1): Handle DECL_FIELD_ABI_IGNORED. > > * g++.target/powerpc/pr94707-1.C: New test. > * g++.target/powerpc/pr94707-2.C: New test. > * g++.target/powerpc/pr94707-3.C: New test. > * g++.target/powerpc/pr94707-4.C: New test. > * g++.target/powerpc/pr94707-5.C: New test. > * g++.target/powerpc/pr94707-4.C: New test. > > --- gcc/tree-core.h.jj 2020-04-08 18:15:36.936946772 +0200 > +++ gcc/tree-core.h 2020-04-28 15:14:06.598814022 +0200 > @@ -1709,7 +1709,8 @@ struct GTY(()) tree_decl_common { > unsigned lang_flag_8 : 1; > > /* In VAR_DECL and PARM_DECL, this is DECL_REGISTER > - IN TRANSLATION_UNIT_DECL, this is TRANSLATION_UNIT_WARN_EMPTY_P. */ > + In TRANSLATION_UNIT_DECL, this is TRANSLATION_UNIT_WARN_EMPTY_P. > + In FIELD_DECL, this is DECL_FIELD_ABI_IGNORED. */ > unsigned decl_flag_0 : 1; > /* In FIELD_DECL, this is DECL_BIT_FIELD > In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL. > --- gcc/tree.h.jj 2020-04-08 18:15:36.939946727 +0200 > +++ gcc/tree.h 2020-04-28 15:13:07.579695258 +0200 > @@ -2750,6 +2750,13 @@ extern void decl_value_expr_insert (tree > /* In a FIELD_DECL, indicates this field should be bit-packed. */ > #define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->base.u.bits.packed_flag) > > +/* In a FIELD_DECL, indicates this field should be ignored for ABI decisions > + like passing/returning containing struct by value. > + Set for C++17 empty base artificial FIELD_DECLs as well as > + empty [[no_unique_address]] non-static data members. */ > +#define DECL_FIELD_ABI_IGNORED(NODE) \ > + (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_0) > + > /* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed > specially. */ > #define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK > (NODE)->decl_common.decl_flag_1) > --- gcc/calls.h.jj 2020-04-27 14:31:09.123020831 +0200 > +++ gcc/calls.h 2020-04-28 15:26:29.221724466 +0200 > @@ -135,6 +135,9 @@ extern tree get_attr_nonstring_decl (tre > extern void maybe_warn_nonstring_arg (tree, tree); > extern bool get_size_range (tree, tree[2], bool = false); > extern rtx rtx_for_static_chain (const_tree, bool); > -extern bool cxx17_empty_base_field_p (const_tree); > +/* FIXME: Remove after all backends are converted. */ > +#define cxx17_empty_base_field_p(t) \ > + (DECL_FIELD_ABI_IGNORED (t) \ > + && !lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (t))) > > #endif // GCC_CALLS_H > --- gcc/calls.c.jj 2020-04-27 14:31:09.117020922 +0200 > +++ gcc/calls.c 2020-04-28 15:26:42.276529517 +0200 > @@ -6261,23 +6261,5 @@ must_pass_va_arg_in_stack (tree type) > return targetm.calls.must_pass_in_stack (arg); > } > > -/* Return true if FIELD is the C++17 empty base field that should > - be ignored for ABI calling convention decisions in order to > - maintain ABI compatibility between C++14 and earlier, which doesn't > - add this FIELD to classes with empty bases, and C++17 and later > - which does. */ > - > -bool > -cxx17_empty_base_field_p (const_tree field) > -{ > - return (TREE_CODE (field) == FIELD_DECL > - && DECL_ARTIFICIAL (field) > - && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)) > - && DECL_SIZE (field) > - && integer_zerop (DECL_SIZE (field)) > - && TYPE_SIZE (TREE_TYPE (field)) > - && !integer_zerop (TYPE_SIZE (TREE_TYPE (field)))); > -} > - > /* Tell the garbage collector about GTY markers in this source file. */ > #include "gt-calls.h" > --- gcc/tree-streamer-out.c.jj 2020-04-08 18:15:36.937946757 +0200 > +++ gcc/tree-streamer-out.c 2020-04-28 15:24:40.062354539 +0200 > @@ -217,6 +217,7 @@ pack_ts_decl_common_value_fields (struct > bp_pack_value (bp, DECL_PACKED (expr), 1); > bp_pack_value (bp, DECL_NONADDRESSABLE_P (expr), 1); > bp_pack_value (bp, DECL_PADDING_P (expr), 1); > + bp_pack_value (bp, DECL_FIELD_ABI_IGNORED (expr), 1); > bp_pack_value (bp, expr->decl_common.off_align, 8); > } > > --- gcc/tree-streamer-in.c.jj 2020-04-08 18:15:36.937946757 +0200 > +++ gcc/tree-streamer-in.c 2020-04-28 15:24:22.511616625 +0200 > @@ -256,6 +256,7 @@ unpack_ts_decl_common_value_fields (stru > DECL_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1); > DECL_NONADDRESSABLE_P (expr) = (unsigned) bp_unpack_value (bp, 1); > DECL_PADDING_P (expr) = (unsigned) bp_unpack_value (bp, 1); > + DECL_FIELD_ABI_IGNORED (expr) = (unsigned) bp_unpack_value (bp, 1); > expr->decl_common.off_align = bp_unpack_value (bp, 8); > } > > --- gcc/lto-streamer-out.c.jj 2020-04-03 10:04:44.775971053 +0200 > +++ gcc/lto-streamer-out.c 2020-04-28 15:23:51.361081794 +0200 > @@ -1080,6 +1080,7 @@ hash_tree (struct streamer_tree_cache_d > hstate.add_flag (DECL_PACKED (t)); > hstate.add_flag (DECL_NONADDRESSABLE_P (t)); > hstate.add_flag (DECL_PADDING_P (t)); > + hstate.add_flag (DECL_FIELD_ABI_IGNORED (t)); > hstate.add_int (DECL_OFFSET_ALIGN (t)); > } > else if (code == VAR_DECL) > --- gcc/config/rs6000/rs6000-call.c.jj 2020-04-23 14:42:26.323839084 +0200 > +++ gcc/config/rs6000/rs6000-call.c 2020-04-28 15:28:11.353199343 +0200 > @@ -5529,7 +5529,7 @@ const struct altivec_builtin_types altiv > > static int > rs6000_aggregate_candidate (const_tree type, machine_mode *modep, > - bool *cxx17_empty_base_seen) > + int *empty_base_seen) > { > machine_mode mode; > HOST_WIDE_INT size; > @@ -5600,7 +5600,7 @@ rs6000_aggregate_candidate (const_tree t > return -1; > > count = rs6000_aggregate_candidate (TREE_TYPE (type), modep, > - cxx17_empty_base_seen); > + empty_base_seen); > if (count == -1 > || !index > || !TYPE_MAX_VALUE (index) > @@ -5638,14 +5638,18 @@ rs6000_aggregate_candidate (const_tree t > if (TREE_CODE (field) != FIELD_DECL) > continue; > > - if (cxx17_empty_base_field_p (field)) > + if (DECL_FIELD_ABI_IGNORED (field)) > { > - *cxx17_empty_base_seen = true; > + if (lookup_attribute ("no_unique_address", > + DECL_ATTRIBUTES (field))) > + *empty_base_seen |= 2; > + else > + *empty_base_seen |= 1; > continue; > } > > sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep, > - cxx17_empty_base_seen); > + empty_base_seen); > if (sub_count < 0) > return -1; > count += sub_count; > @@ -5679,7 +5683,7 @@ rs6000_aggregate_candidate (const_tree t > continue; > > sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep, > - cxx17_empty_base_seen); > + empty_base_seen); > if (sub_count < 0) > return -1; > count = count > sub_count ? count : sub_count; > @@ -5720,9 +5724,9 @@ rs6000_discover_homogeneous_aggregate (m > && AGGREGATE_TYPE_P (type)) > { > machine_mode field_mode = VOIDmode; > - bool cxx17_empty_base_seen = false; > + int empty_base_seen = 0; > int field_count = rs6000_aggregate_candidate (type, &field_mode, > - &cxx17_empty_base_seen); > + &empty_base_seen); > > if (field_count > 0) > { > @@ -5737,16 +5741,22 @@ rs6000_discover_homogeneous_aggregate (m > *elt_mode = field_mode; > if (n_elts) > *n_elts = field_count; > - if (cxx17_empty_base_seen && warn_psabi) > + if (empty_base_seen && warn_psabi) > { > static unsigned last_reported_type_uid; > unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (type)); > if (uid != last_reported_type_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 (empty_base_seen & 1) > + 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); > + else > + inform (input_location, > + "parameter passing for argument of type %qT " > + "with %<[[no_unique_address]]%> members " > + "changed in GCC 10.1", type); > last_reported_type_uid = uid; > } > } > --- gcc/config/rs6000/rs6000.c.jj 2020-04-27 09:11:14.090608782 +0200 > +++ gcc/config/rs6000/rs6000.c 2020-04-28 15:29:25.166097098 +0200 > @@ -7204,7 +7204,9 @@ rs6000_special_round_type_align (tree ty > tree field = TYPE_FIELDS (type); > > /* Skip all non field decls */ > - while (field != NULL && TREE_CODE (field) != FIELD_DECL) > + while (field != NULL > + && (TREE_CODE (field) != FIELD_DECL > + || DECL_FIELD_ABI_IGNORED (field))) > field = DECL_CHAIN (field); > > if (field != NULL && field != type) > @@ -7236,7 +7238,9 @@ darwin_rs6000_special_round_type_align ( > do { > tree field = TYPE_FIELDS (type); > /* Skip all non field decls */ > - while (field != NULL && TREE_CODE (field) != FIELD_DECL) > + while (field != NULL > + && (TREE_CODE (field) != FIELD_DECL > + || DECL_FIELD_ABI_IGNORED (field))) > field = DECL_CHAIN (field); > if (! field) > break; > --- gcc/cp/class.c.jj 2020-04-28 16:15:39.570540960 +0200 > +++ gcc/cp/class.c 2020-04-28 16:35:18.423859735 +0200 > @@ -4515,6 +4515,7 @@ build_base_field (record_layout_info rli > DECL_FIELD_OFFSET (decl) = BINFO_OFFSET (binfo); > DECL_FIELD_BIT_OFFSET (decl) = bitsize_zero_node; > SET_DECL_OFFSET_ALIGN (decl, BITS_PER_UNIT); > + DECL_FIELD_ABI_IGNORED (decl) = 1; > } > > /* An empty virtual base causes a class to be non-empty > @@ -6522,7 +6523,10 @@ layout_class_type (tree t, tree *virtual > SET_DECL_MODE (field, TYPE_MODE (type)); > } > else if (might_overlap && is_empty_class (type)) > - layout_empty_base_or_field (rli, field, empty_base_offsets); > + { > + DECL_FIELD_ABI_IGNORED (field) = 1; > + layout_empty_base_or_field (rli, field, empty_base_offsets); > + } > else > layout_nonempty_base_or_field (rli, field, NULL_TREE, > empty_base_offsets); > --- gcc/lto/lto-common.c.jj 2020-04-17 14:18:44.357438048 +0200 > +++ gcc/lto/lto-common.c 2020-04-28 17:53:04.809821198 +0200 > @@ -1179,6 +1179,7 @@ compare_tree_sccs_1 (tree t1, tree t2, t > compare_values (DECL_PACKED); > compare_values (DECL_NONADDRESSABLE_P); > compare_values (DECL_PADDING_P); > + compare_values (DECL_FIELD_ABI_IGNORED); > compare_values (DECL_OFFSET_ALIGN); > } > else if (code == VAR_DECL) > --- gcc/testsuite/g++.target/powerpc/pr94707-1.C.jj 2020-04-28 > 13:26:01.417418105 +0200 > +++ gcc/testsuite/g++.target/powerpc/pr94707-1.C 2020-04-28 > 13:25:19.555046878 +0200 > @@ -0,0 +1,38 @@ > +// PR target/94707 > +// { dg-do compile { target powerpc_elfv2 } } > +// { dg-options "-O2 -std=c++14" } > +// Test that for all the calls in this testcase the C++17 empty base > +// artificial fields and [[no_unique_address]] empty class non-static > +// data members are ignored in the decision about passing homogeneous > +// arguments. > +// { dg-final { scan-assembler-times {(?n)^\s+lfs\s+(?:%f)?4,} 7 } } > + > +struct X { }; > +struct Y { int : 0; }; > +struct Z { int : 0; Y y; }; > +struct U : public X { X q; }; > +struct A { float a, b, c, d; }; > +struct B : public X { float a, b, c, d; }; > +struct C : public Y { float a, b, c, d; }; > +struct D : public Z { float a, b, c, d; }; > +struct E : public U { float a, b, c, d; }; > +struct F { [[no_unique_address]] X x; float a, b, c, d; }; > +struct G { [[no_unique_address]] Y y; float a, b, c, d; }; > +struct H { [[no_unique_address]] Z z; float a, b, c, d; }; > +struct I { [[no_unique_address]] U u; float a, b, c, d; }; > +struct J { float a, b; [[no_unique_address]] X x; float c, d; }; > +struct K { float a, b; [[no_unique_address]] Y y; float c, d; }; > +struct L { float a, b; [[no_unique_address]] Z z; float c, d; }; > +struct M { float a, b; [[no_unique_address]] U u; float c, d; }; > +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s > (s); return 0; } > +// { dg-message "parameter passing for argument of type 'F' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-1 } > +// { dg-message "parameter passing for argument of type 'G' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-2 } > +// { dg-message "parameter passing for argument of type 'J' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-3 } > +// { dg-message "parameter passing for argument of type 'K' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-4 } > +T (A, a) > +T (B, b) > +T (C, c) > +T (F, f) > +T (G, g) > +T (J, j) > +T (K, k) > --- gcc/testsuite/g++.target/powerpc/pr94707-2.C.jj 2020-04-28 > 13:26:04.782367567 +0200 > +++ gcc/testsuite/g++.target/powerpc/pr94707-2.C 2020-04-28 > 13:25:29.240901395 +0200 > @@ -0,0 +1,34 @@ > +// PR target/94707 > +// { dg-do compile { target powerpc_elfv2 } } > +// { dg-options "-O2 -std=c++14" } > +// Test that for no calls in this testcase the C++17 empty base > +// artificial fields and [[no_unique_address]] empty class non-static > +// data members are ignored in the decision about passing homogeneous > +// arguments. > +// { dg-final { scan-assembler-not {(?n)^\s+lfs\s+(?:%f)?4,} } } > + > +struct X { }; > +struct Y { int : 0; }; > +struct Z { int : 0; Y y; }; > +struct U : public X { X q; }; > +struct A { float a, b, c, d; }; > +struct B : public X { float a, b, c, d; }; > +struct C : public Y { float a, b, c, d; }; > +struct D : public Z { float a, b, c, d; }; > +struct E : public U { float a, b, c, d; }; > +struct F { [[no_unique_address]] X x; float a, b, c, d; }; > +struct G { [[no_unique_address]] Y y; float a, b, c, d; }; > +struct H { [[no_unique_address]] Z z; float a, b, c, d; }; > +struct I { [[no_unique_address]] U u; float a, b, c, d; }; > +struct J { float a, b; [[no_unique_address]] X x; float c, d; }; > +struct K { float a, b; [[no_unique_address]] Y y; float c, d; }; > +struct L { float a, b; [[no_unique_address]] Z z; float c, d; }; > +struct M { float a, b; [[no_unique_address]] U u; float c, d; }; > +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s > (s); return 0; } > +// { dg-bogus "parameter passing for argument of type" } > +T (D, d) > +T (E, e) > +T (H, h) > +T (I, i) > +T (L, l) > +T (M, m) > --- gcc/testsuite/g++.target/powerpc/pr94707-3.C.jj 2020-04-28 > 13:26:07.485326967 +0200 > +++ gcc/testsuite/g++.target/powerpc/pr94707-3.C 2020-04-28 > 13:25:40.206736691 +0200 > @@ -0,0 +1,40 @@ > +// PR target/94707 > +// { dg-do compile { target powerpc_elfv2 } } > +// { dg-options "-O2 -std=c++17" } > +// Test that for all the calls in this testcase the C++17 empty base > +// artificial fields and [[no_unique_address]] empty class non-static > +// data members are ignored in the decision about passing homogeneous > +// arguments. > +// { dg-final { scan-assembler-times {(?n)^\s+lfs\s+(?:%f)?4,} 7 } } > + > +struct X { }; > +struct Y { int : 0; }; > +struct Z { int : 0; Y y; }; > +struct U : public X { X q; }; > +struct A { float a, b, c, d; }; > +struct B : public X { float a, b, c, d; }; > +struct C : public Y { float a, b, c, d; }; > +struct D : public Z { float a, b, c, d; }; > +struct E : public U { float a, b, c, d; }; > +struct F { [[no_unique_address]] X x; float a, b, c, d; }; > +struct G { [[no_unique_address]] Y y; float a, b, c, d; }; > +struct H { [[no_unique_address]] Z z; float a, b, c, d; }; > +struct I { [[no_unique_address]] U u; float a, b, c, d; }; > +struct J { float a, b; [[no_unique_address]] X x; float c, d; }; > +struct K { float a, b; [[no_unique_address]] Y y; float c, d; }; > +struct L { float a, b; [[no_unique_address]] Z z; float c, d; }; > +struct M { float a, b; [[no_unique_address]] U u; float c, d; }; > +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s > (s); return 0; } > +// { dg-message "parameter passing for argument of type 'B' when C\\+\\+17 > is enabled changed to match C\\+\\+14 in GCC 10.1" "" { target *-*-* } .-1 } > +// { dg-message "parameter passing for argument of type 'C' when C\\+\\+17 > is enabled changed to match C\\+\\+14 in GCC 10.1" "" { target *-*-* } .-2 } > +// { dg-message "parameter passing for argument of type 'F' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-3 } > +// { dg-message "parameter passing for argument of type 'G' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-4 } > +// { dg-message "parameter passing for argument of type 'J' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-5 } > +// { dg-message "parameter passing for argument of type 'K' with > '\\\[\\\[no_unique_address\\\]\\\]' members changed in GCC 10.1" "" { target > *-*-* } .-6 } > +T (A, a) > +T (B, b) > +T (C, c) > +T (F, f) > +T (G, g) > +T (J, j) > +T (K, k) > --- gcc/testsuite/g++.target/powerpc/pr94707-4.C.jj 2020-04-28 > 13:26:10.257285341 +0200 > +++ gcc/testsuite/g++.target/powerpc/pr94707-4.C 2020-04-28 > 13:25:56.925485580 +0200 > @@ -0,0 +1,34 @@ > +// PR target/94707 > +// { dg-do compile { target powerpc_elfv2 } } > +// { dg-options "-O2 -std=c++17" } > +// Test that for no calls in this testcase the C++17 empty base > +// artificial fields and [[no_unique_address]] empty class non-static > +// data members are ignored in the decision about passing homogeneous > +// arguments. > +// { dg-final { scan-assembler-not {(?n)^\s+lfs\s+(?:%f)?4,} } } > + > +struct X { }; > +struct Y { int : 0; }; > +struct Z { int : 0; Y y; }; > +struct U : public X { X q; }; > +struct A { float a, b, c, d; }; > +struct B : public X { float a, b, c, d; }; > +struct C : public Y { float a, b, c, d; }; > +struct D : public Z { float a, b, c, d; }; > +struct E : public U { float a, b, c, d; }; > +struct F { [[no_unique_address]] X x; float a, b, c, d; }; > +struct G { [[no_unique_address]] Y y; float a, b, c, d; }; > +struct H { [[no_unique_address]] Z z; float a, b, c, d; }; > +struct I { [[no_unique_address]] U u; float a, b, c, d; }; > +struct J { float a, b; [[no_unique_address]] X x; float c, d; }; > +struct K { float a, b; [[no_unique_address]] Y y; float c, d; }; > +struct L { float a, b; [[no_unique_address]] Z z; float c, d; }; > +struct M { float a, b; [[no_unique_address]] U u; float c, d; }; > +#define T(S, s) extern S s; extern void foo##s (S); int bar##s () { foo##s > (s); return 0; } > +// { dg-bogus "parameter passing for argument of type" } > +T (D, d) > +T (E, e) > +T (H, h) > +T (I, i) > +T (L, l) > +T (M, m) > --- gcc/testsuite/g++.target/powerpc/pr94707-5.C.jj 2020-04-28 > 16:33:53.431130852 +0200 > +++ gcc/testsuite/g++.target/powerpc/pr94707-5.C 2020-04-28 > 16:47:31.488901028 +0200 > @@ -0,0 +1,35 @@ > +// PR target/94707 > +// { dg-do compile { target powerpc*-*-darwin* } } > +// { dg-require-effective-target ilp32 } > +// { dg-options "-std=c++14" } > + > +struct X { }; > +struct Y { int : 0; }; > +struct Z { int : 0; Y y; }; > +struct U : public X { X q; }; > +struct A { double a; }; > +struct B : public X { double a; }; > +struct C : public Y { double a; }; > +struct D : public Z { double a; }; > +struct E : public U { double a; }; > +struct F { [[no_unique_address]] X x; double a; }; > +struct G { [[no_unique_address]] Y y; double a; }; > +struct H { [[no_unique_address]] Z z; double a; }; > +struct I { [[no_unique_address]] U u; double a; }; > +struct J { double a; [[no_unique_address]] X x; }; > +struct K { double a; [[no_unique_address]] Y y; }; > +struct L { double a; [[no_unique_address]] Z z; }; > +struct M { double a; [[no_unique_address]] U u; }; > +static_assert (__alignof__ (A) == 8, ""); > +static_assert (__alignof__ (B) == 8, ""); > +static_assert (__alignof__ (C) == 8, ""); > +static_assert (__alignof__ (D) == 4, ""); > +static_assert (__alignof__ (E) == 4, ""); > +static_assert (__alignof__ (F) == 8, ""); > +static_assert (__alignof__ (G) == 8, ""); > +static_assert (__alignof__ (H) == 4, ""); > +static_assert (__alignof__ (I) == 4, ""); > +static_assert (__alignof__ (J) == 8, ""); > +static_assert (__alignof__ (K) == 8, ""); > +static_assert (__alignof__ (L) == 8, ""); > +static_assert (__alignof__ (M) == 8, ""); > --- gcc/testsuite/g++.target/powerpc/pr94707-6.C.jj 2020-04-28 > 16:33:53.431130852 +0200 > +++ gcc/testsuite/g++.target/powerpc/pr94707-6.C 2020-04-28 > 16:47:54.056563731 +0200 > @@ -0,0 +1,6 @@ > +// PR target/94707 > +// { dg-do compile { target powerpc*-*-darwin* } } > +// { dg-require-effective-target ilp32 } > +// { dg-options "-O2 -std=c++17" } > + > +#include "pr94707-5.C" > > > Jakub >