On Mon, Apr 27, 2020 at 05:11:38PM -0400, Jason Merrill wrote: > > struct empty { }; > > struct X { [[no_unique_address]] empty e; }; > > > > and have them be layout compatible, otherwise the attribute is useless > > to the standard library. > > Why are zero-size fields changing layout/parameter passing in these ABIs, > anyway?
There are many affected ABIs and they have different rules. Some are e.g. looking for homogenous aggregates, say struct S { float a, b, c, d, e; }; contains just float fields and is passed in floating point registers in some ABIs, and that is how C++14 represented even struct empty {}; struct S : public empty { float a, b, c, d, e; }; and with the changes from last week also the C++17. Thus, I guess we want to handle struct T { [[no_unique_address]] empty x; float a, b, c, d, e; }; that way too. The question is shall that be only when it is the first field, or at any position as long as it is [[no_unique_address]] FIELD_DECL with DECL_SIZE of bitsize_zero? Or do we have to further check that it really doesn't contain any fields other than empty classes? E.g. some of the ABIs pass differently: struct A {}; struct B { A a; float b, c, d; }; struct C { int : 0; }; struct D { C a; float b, c, d; }; because the zero sized bitfield is spelled in the ABI as causing different behavior. Other ABIs look for first field and do something if it is of some kind (or if it is the first and only say float or vector field). E.g. the powerpc-darwin or powerpc*-aix* ABIs do different alignment depending on if it is: struct E {}; struct F { double d; }; or struct G { E e; double d; }; One can just grep the backends for TYPE_FIELDS walks... Jakub