From 1fda8abadb1a9d068ea1d0fb236e3383a6b23e7b Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 6 Aug 2015 10:42:38 +0900 Subject: [PATCH] fix Issue 14862 - Constructor of overlapped struct does not initialize correctly global variables --- src/aggregate.d | 51 --------------------------------------- src/aggregate.h | 2 -- src/dinterpret.d | 9 +++---- test/runnable/interpret.d | 29 ++++++++++++++++++++++ 4 files changed, 33 insertions(+), 58 deletions(-) diff --git a/src/aggregate.d b/src/aggregate.d index 40d52a0ab6cd..c7b2c447cab6 100644 --- a/src/aggregate.d +++ b/src/aggregate.d @@ -355,57 +355,6 @@ public: return type; } - /**************************************** - * If field[indx] is not part of a union, return indx. - * Otherwise, return the lowest field index of the union. - */ - final int firstFieldInUnion(int indx) - { - if (isUnionDeclaration()) - return 0; - VarDeclaration vd = fields[indx]; - int firstNonZero = indx; // first index in the union with non-zero size - for (;;) - { - if (indx == 0) - return firstNonZero; - VarDeclaration v = fields[indx - 1]; - if (v.offset != vd.offset) - return firstNonZero; - --indx; - /* If it is a zero-length field, it's ambiguous: we don't know if it is - * in the union unless we find an earlier non-zero sized field with the - * same offset. - */ - if (v.size(loc) != 0) - firstNonZero = indx; - } - } - - /**************************************** - * Count the number of fields starting at firstIndex which are part of the - * same union as field[firstIndex]. If not a union, return 1. - */ - final int numFieldsInUnion(int firstIndex) - { - VarDeclaration vd = fields[firstIndex]; - /* If it is a zero-length field, AND we can't find an earlier non-zero - * sized field with the same offset, we assume it's not part of a union. - */ - if (vd.size(loc) == 0 && !isUnionDeclaration() && firstFieldInUnion(firstIndex) == firstIndex) - return 1; - int count = 1; - for (size_t i = firstIndex + 1; i < fields.dim; ++i) - { - VarDeclaration v = fields[i]; - // If offsets are different, they are not in the same union - if (v.offset != vd.offset) - break; - ++count; - } - return count; - } - // is aggregate deprecated? final bool isDeprecated() { diff --git a/src/aggregate.h b/src/aggregate.h index 69064253170b..a6ff97238d0e 100644 --- a/src/aggregate.h +++ b/src/aggregate.h @@ -122,8 +122,6 @@ class AggregateDeclaration : public ScopeDsymbol unsigned memsize, unsigned memalignsize, structalign_t memalign, unsigned *paggsize, unsigned *paggalignsize, bool isunion); Type *getType(); - int firstFieldInUnion(int indx); // first field in union that includes indx - int numFieldsInUnion(int firstIndex); // #fields in union starting at index bool isDeprecated(); // is aggregate deprecated? bool isNested(); void makeNested(); diff --git a/src/dinterpret.d b/src/dinterpret.d index 5f846625fb32..e27b07e4195c 100644 --- a/src/dinterpret.d +++ b/src/dinterpret.d @@ -3682,14 +3682,13 @@ public: } assert(0 <= fieldi && fieldi < sle.elements.dim); // If it's a union, set all other members of this union to void - if (ex.op == TOKstructliteral) + if (ex.op == TOKstructliteral && v.overlapped) { assert(sle.sd); - int unionStart = sle.sd.firstFieldInUnion(fieldi); - int unionSize = sle.sd.numFieldsInUnion(fieldi); - for (int i = unionStart; i < unionStart + unionSize; ++i) + for (size_t i = 0; i < sle.sd.fields.dim; i++) { - if (i == fieldi) + VarDeclaration v2 = sle.sd.fields[i]; + if (!v.isOverlappedWith(v2)) continue; Expression* exp = &(*sle.elements)[i]; if ((*exp).op != TOKvoid) diff --git a/test/runnable/interpret.d b/test/runnable/interpret.d index 4a79302a0920..e786236f510c 100644 --- a/test/runnable/interpret.d +++ b/test/runnable/interpret.d @@ -3323,6 +3323,34 @@ void test113() } } +/************************************************/ +// 14862 + +struct S14862 +{ + union + { + struct { uint hi, lo; } + ulong data; + } + + this(ulong data) + { + this.data = data; + } +} + +void test14862() +{ + S14862 s14862 = S14862(123UL); + enum S14862 e14862 = S14862(123UL); + static S14862 g14862 = S14862(123UL); + + assert(s14862.data == 123UL); // OK + assert(e14862.data == 123UL); // OK + assert(g14862.data == 123UL); // OK <- fail +} + /************************************************/ int main() @@ -3443,6 +3471,7 @@ int main() test8818(); test9023(); test9954(); + test14862(); printf("Success\n"); return 0;