<html>
    <head>
      <base href="https://bugs.llvm.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 - Dangerous fld usage"
   href="https://bugs.llvm.org/show_bug.cgi?id=44302">44302</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Dangerous fld usage
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

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

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>zamazan4ik@tut.by
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>clang(trunk) with '-O3 -m32' for this code:


#include <stdint.h>
typedef int SQObjectType;
typedef int64_t SQInteger;

union SQObjectValue
{
  SQInteger integer;
  float real;
};


struct  SQObject
{
    SQObjectType _type;
    SQObjectValue _unVal;
};

SQInteger toint(SQObject &i)
{
    return i._type == 10 ? (SQInteger)(i._unVal.real) :
                         (i._unVal.integer);
}


generates that assembly:

toint(SQObject&):                     # @toint(SQObject&)
        sub     esp, 20
        mov     ecx, dword ptr [esp + 24]
        movss   xmm0, dword ptr [ecx + 4
        movss   dword ptr [esp + 8], xmm0
        fld     dword ptr [esp + 8] #here floating point exception will be
thrown, if provided tagged union is int64_t == -1
        fnstcw  word ptr [esp + 4]
        movzx   eax, word ptr [esp + 4]
        or      eax, 3072
        mov     word ptr [esp + 6], ax
        fldcw   word ptr [esp + 6]
        fistp   qword ptr [esp + 8]
        fldcw   word ptr [esp + 4]
        cmp     dword ptr [ecx], 10
        jne     .LBB0_1
        mov     eax, dword ptr [esp + 8]
        mov     edx, dword ptr [esp + 12]
        add     esp, 20
        ret
.LBB0_1:
        mov     eax, dword ptr [ecx + 4]
        mov     edx, dword ptr [ecx + 8]
        add     esp, 20
        ret


gcc(trunk) with '-O3 -m32' generates this:

toint(SQObject&):
        sub     esp, 20
        mov     eax, DWORD PTR [esp+24]
        cmp     DWORD PTR [eax], 10  #first compare for type, than do float to
int64_t conversion!
        je      .L7
        mov     edx, DWORD PTR [eax+8]
        mov     eax, DWORD PTR [eax+4]
        add     esp, 20
        ret
.L7:
        fld     DWORD PTR [eax+4]
        fnstcw  WORD PTR [esp+14]
        movzx   eax, WORD PTR [esp+14]
        or      ah, 12
        mov     WORD PTR [esp+12], ax
        fldcw   WORD PTR [esp+12]
        fistp   QWORD PTR [esp]
        fldcw   WORD PTR [esp+14]
        mov     eax, DWORD PTR [esp]
        mov     edx, DWORD PTR [esp+4]
        add     esp, 20
        ret

So, first of all clang generates dangerous code that will result in
unconditional floating point conversion even if provided SQObject is actually
an Integer (of certain values).
Secondly, gcc code is slightly more optimal (not important).

In addition, version with pointer to SqObject is for some reason works
correctly, unlike reference.
(But it is not possible to workaround buggy code generation by getting pointer
to reference, probably due to inlining).

Live code example : <a href="https://godbolt.org/z/gHf9YZ">https://godbolt.org/z/gHf9YZ</a></pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>