http://bugzilla.gdcproject.org/show_bug.cgi?id=186
Bug ID: 186 Summary: Struct with union of struct and size_t field gets wrong optimization if initialized on same line as declaration Product: GDC Version: 4.9.x Hardware: x86_64 OS: Linux Status: NEW Severity: major Priority: Normal Component: gdc Assignee: ibuc...@gdcproject.org Reporter: li...@weka.io Reproduced on commit b022dd4cac195d85e9c3a6a37f2501a07ade455a from April 7 (4.9.x branch) The following code: ------------------------- module test; import std.stdio; import std.string; struct StructWithUnion { union { struct { ubyte fieldA; byte fieldB = -1; byte fieldC = -1; } size_t _complete; } this(size_t complete) { this._complete = complete; } } void printSWUInfo(in StructWithUnion obj, byte fieldB) { writefln("Struct is %s fieldA %s fieldB %s fieldC %s complete %s, explicit fieldB %s", obj, obj.fieldA, obj.fieldB, obj.fieldC, obj._complete, fieldB); } int myFunction(size_t val) { StructWithUnion obj = StructWithUnion(val); // Fails when the initialization happens on same line of variable declaration printSWUInfo(obj, obj.fieldB); writefln("Struct is %s fieldA %s fieldB %s fieldC is %s complete %s", obj, obj.fieldA, obj.fieldB, obj.fieldC, obj._complete); obj = StructWithUnion(val); // works ok when initialized without declaring. printSWUInfo(obj, obj.fieldB); writefln("Struct is %s fieldA %s fieldB %s fieldC is %s complete %s", obj, obj.fieldA, obj.fieldB, obj.fieldC, obj._complete); return 0; } int main() { return myFunction(2); } --------------------------------- Produces the following output: bash-4.3# /opt/gdc/bin/gdc -ggdb -O -ogtest test.d && ./gtest Struct is const(StructWithUnion)(2, 0, 0, 2) fieldA 2 fieldB 0 fieldC 0 complete 2, explicit fieldB -1 Struct is StructWithUnion(2, 0, 0, 2) fieldA 0 fieldB -1 fieldC is -1 complete 2 Struct is const(StructWithUnion)(2, 0, 0, 2) fieldA 2 fieldB 0 fieldC 0 complete 2, explicit fieldB 0 Struct is StructWithUnion(2, 0, 0, 2) fieldA 2 fieldB 0 fieldC is 0 complete 2 You can see that in myFunction, after initializing obj on the same line fieldB and fieldC should have been 0, but are actually -1. When comparing the generated assembly of the call to printSWUInfo, the one of line 25 (same line as declaration): /mnt/test.d:25 404ca5: be ff ff ff ff mov $0xffffffff,%esi // second argument is always -1 404caa: e8 0d ff ff ff callq 404bbc <_D4test12printSWUInfoFxS4test15StructWithUniongZv> No need to set %edi as it is already set from the function call. Then on line 29 (initialization not on line of declaration): 404ca2: 48 89 fb mov %rdi,%rbx // Saving 'val' to %rbx on entry . . /mnt/test.d:29 404d3d: 41 89 dc mov %ebx,%r12d // preparing r12d for fieldB calaulation 404d40: 66 41 c1 fc 08 sar $0x8,%r12w // Yuppie! "calculating" 404d45: 44 89 e6 mov %r12d,%esi 404d48: 48 89 df mov %rbx,%rdi 404d4b: e8 6c fe ff ff callq 404bbc <_D4test12printSWUInfoFxS4test15StructWithUniongZv> --- So for some reason the optimizer ignores the need to calculate fieldB in the case that the initialization was performed on the line of variable declaration. -- You are receiving this mail because: You are watching all bug changes.