mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 07:30:27 +08:00
d: Fix assignment to anonymous union member corrupts sibling members in struct
gcc/d/ChangeLog: PR d/92309 * types.cc (fixup_anonymous_offset): Don't set DECL_FIELD_OFFSET on anonymous fields. gcc/testsuite/ChangeLog: PR d/92309 * gdc.dg/pr92309.d: New test.
This commit is contained in:
parent
c62f5e6e1f
commit
2691ffe6db
@ -1,3 +1,9 @@
|
||||
2020-03-16 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
PR d/92309
|
||||
* types.cc (fixup_anonymous_offset): Don't set DECL_FIELD_OFFSET on
|
||||
anonymous fields.
|
||||
|
||||
2020-03-16 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
PR d/92216
|
||||
|
@ -234,16 +234,20 @@ insert_aggregate_field (tree type, tree field, size_t offset)
|
||||
static void
|
||||
fixup_anonymous_offset (tree fields, tree offset)
|
||||
{
|
||||
/* No adjustment in field offset required. */
|
||||
if (integer_zerop (offset))
|
||||
return;
|
||||
|
||||
while (fields != NULL_TREE)
|
||||
{
|
||||
/* Traverse all nested anonymous aggregates to update their offset.
|
||||
Set the anonymous decl offset to its first member. */
|
||||
/* Traverse all nested anonymous aggregates to update the offset of their
|
||||
fields. Note that the anonymous field itself is not adjusted, as it
|
||||
already has an offset relative to its outer aggregate. */
|
||||
tree ftype = TREE_TYPE (fields);
|
||||
if (TYPE_NAME (ftype) && IDENTIFIER_ANON_P (TYPE_IDENTIFIER (ftype)))
|
||||
{
|
||||
tree vfields = TYPE_FIELDS (ftype);
|
||||
fixup_anonymous_offset (vfields, offset);
|
||||
DECL_FIELD_OFFSET (fields) = DECL_FIELD_OFFSET (vfields);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,3 +1,8 @@
|
||||
2020-03-16 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
PR d/92309
|
||||
* gdc.dg/pr92309.d: New test.
|
||||
|
||||
2020-03-16 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
PR d/92216
|
||||
|
25
gcc/testsuite/gdc.dg/pr92309.d
Normal file
25
gcc/testsuite/gdc.dg/pr92309.d
Normal file
@ -0,0 +1,25 @@
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92309
|
||||
// { dg-do run { target hw } }
|
||||
// { dg-skip-if "needs gcc/config.d" { ! d_runtime } }
|
||||
|
||||
union U
|
||||
{
|
||||
struct
|
||||
{
|
||||
size_t a;
|
||||
size_t b;
|
||||
union
|
||||
{
|
||||
size_t c;
|
||||
size_t d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
U u;
|
||||
assert(u.a == 0);
|
||||
u.d = 1;
|
||||
assert(u.a == 0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user