On Tue, Dec 03, 2019 at 02:07:02AM -0500, Jason Merrill wrote: > On 12/2/19 5:09 PM, Marek Polacek wrote: > > On Mon, Dec 02, 2019 at 12:09:17PM -0500, Jason Merrill wrote: > > > On 12/1/19 8:09 PM, Marek Polacek wrote: > > > > + || (skip_empty > > > > + && is_really_empty_class (TREE_TYPE (field), > > > > > > This should probably check DECL_SIZE (field) == size_zero_node instead, > > > since that will properly distinguish between overlapping and > > > non-overlapping > > > data members of empty class type. And please test how this works with > > > data > > > members of empty class type both with and without [[no_unique_address]]. > > > > I don't think that's possible -- empty classes in C++ have sizeof(char), > > unless > > their only member is char[0], then their DECL_SIZE is 0. > > I think you're talking about the TYPE_SIZE of the class, and I'm talking > about the DECL_SIZE of the FIELD_DECL.
I'm really looking at the DECL_SIZE: Breakpoint 5, next_initializable_field (field=<field_decl 0x7fffea90dc78 s>, skip_empty=true) at /home/mpolacek/src/gcc/gcc/cp/decl.c:5928 5928 && is_really_empty_class (TREE_TYPE (field), (gdb) p field $1 = <field_decl 0x7fffea90dc78 s> (gdb) p DECL_SIZE($1) $2 = <integer_cst 0x7fffea8e0f60> (gdb) pge 8 This is constexpr-init8.C: struct S { constexpr S(int) {} }; struct W { constexpr W(int) : s(8), p() {} S s; int *p; }; constexpr auto a = W(42); I think that's because layout_class_type has: 6491 else if (might_overlap && is_empty_class (type)) 6492 layout_empty_base_or_field (rli, field, empty_base_offsets); 6493 else 6494 layout_nonempty_base_or_field (rli, field, NULL_TREE, 6495 empty_base_offsets); and here might_overlap is false because 's' doesn't have [[no_unique_address]]. So we emit the FIELD_DECL with size 8. Its type CLASSTYPE_SIZE is 0 though. I don't know but I'd rather not mess with this... > > I've added two testcases: constexpr-init13.C and constexpr-init14.C. Is > > there > > another scenario regarding [[no_unique_address]] that you want me to test? > > I think the classes with empty base fields need to have another initialized > field after them to have a chance of tripping > > if (idx != field) And sure enough, that's exactly the case for struct E { constexpr E() = default; constexpr E(int) {} }; struct S { E e; int i; constexpr S() : e{} , i(11) { } }; constexpr S s; And that's even without [[no_unique_address]]. So it's a valid concern. It's unclear to me how this should be resolved. -- Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA