diff --git a/compiler/src/dmd/dstruct.d b/compiler/src/dmd/dstruct.d index 28a00e0922..26a9de5439 100644 --- a/compiler/src/dmd/dstruct.d +++ b/compiler/src/dmd/dstruct.d @@ -233,8 +233,12 @@ extern (C++) class StructDeclaration : AggregateDeclaration auto lastOffset = -1; foreach (vd; fields) { + // First skip zero sized fields + if (vd.type.size(vd.loc) == 0) + continue; + // only consider first sized member of an (anonymous) union - if (vd.overlapped && vd.offset == lastOffset && vd.type.size(vd.loc) != 0) + if (vd.overlapped && vd.offset == lastOffset) continue; lastOffset = vd.offset; @@ -246,10 +250,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration */ continue; - // Zero size fields are zero initialized - if (vd.type.size(vd.loc) == 0) - continue; - // Examine init to see if it is all 0s. auto exp = vd.getConstInitializer(); if (!exp || !_isZeroInit(exp)) diff --git a/compiler/test/compilable/isZeroInit.d b/compiler/test/compilable/isZeroInit.d index 183f01bcd5..342dc07bf0 100644 --- a/compiler/test/compilable/isZeroInit.d +++ b/compiler/test/compilable/isZeroInit.d @@ -103,7 +103,6 @@ union U float x = 0; float y; } - static assert(__traits(isZeroInit, U)); union U2 @@ -111,5 +110,13 @@ union U2 float x; int y; } - static assert(!__traits(isZeroInit, U2)); + +struct S8 { + int[0] dummy; // same offset as anon union, but doesn't overlap; should be ignored anyway for zero-init check + union { + float f; // is the first member of the anon union and must be checked + int i; + } +} +static assert(!__traits(isZeroInit, S8));