<html>
    <head>
      <base href="http://bugzilla.gdcproject.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Struct with union of struct and size_t field gets wrong optimization if initialized on same line as declaration"
   href="http://bugzilla.gdcproject.org/show_bug.cgi?id=186">186</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Struct with union of struct and size_t field gets wrong optimization if initialized on same line as declaration
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>GDC
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>4.9.x
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>x86_64
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>major
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>Normal
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>gdc
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>ibuclaw@gdcproject.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>liran@weka.io
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are watching all bug changes.</li>
      </ul>
    </body>
</html>