www.digitalmars.com         C & C++   DMDScript  

D.gnu - [Bug 186] New: Struct with union of struct and size_t field gets

Date: Wed, 20 May 2015 12:30:32 +0100
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"

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: ibuclaw gdcproject.org
          Reporter: liran 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.
May 20 2015