On 7/30/21 11:23 AM, Jakub Jelinek wrote:
On Fri, Jul 30, 2021 at 11:00:26AM -0400, Jason Merrill wrote:
Patch attached.
LGTM (which would mean I'll need to replace that particular test union
with a different one which will have just a non-std-layout member of the
anon struct, see below), but I guess we want a testcase for this, e.g.
struct E { };
struct X { int a; struct : public E { short b; long c; }; long long d; };
union Y { int a; struct : public E { short b; long c; }; long long d; };
will do it.
I've now committed this change.
But standard layout means that even all the non-static members of the struct
need to be standard-layout, that seems an unnecessary requirement for
anon structures to me.
Good point.
But then, if the anonymous struct is non-standard-layout, that should make
the enclosing class non-standard-layout as well, so we should never need to
consider in the pointer-interconv code whether the anonymous struct is
standard-layout.
For non-std-layout anon struct in a non-union class sure.
But, for non-std-layout anon struct in a union, while it makes the union
also non-std-layout, pointer-interconvertibility doesn't care about
std-layout, even in non-std-layout unions address of each of the union member
is pointer-interconvertible with the address of the whole union object.
Ah, right, I remembered that yesterday, but forgot this morning...
So the handling in your revised patch is good; let's not worry about the
case you mentioned with an anonymous struct member of the same type as
another union member.
Though
+ if ((TREE_CODE (type) != UNION_TYPE
This line could use either a comment or to be dropped; it's true that if
type is non-union, we can skip the other checks because we know that any
anonymous struct member must be standard-layout, but the other checks
are cheap enough that I'm inclined to omit this one.
OK either way and with the testcase adjustments for my patch.
+ || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
|| std_layout_type_p (TREE_TYPE (field)))
&& first_nonstatic_data_member_p (TREE_TYPE (field), membertype))