[llvm-bugs] [Bug 44302] New: Dangerous fld usage
via llvm-bugs
llvm-bugs at lists.llvm.org
Sat Dec 14 16:32:43 PST 2019
https://bugs.llvm.org/show_bug.cgi?id=44302
Bug ID: 44302
Summary: Dangerous fld usage
Product: clang
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: C++
Assignee: unassignedclangbugs at nondot.org
Reporter: zamazan4ik at tut.by
CC: blitzrakete at gmail.com, dgregor at apple.com,
erik.pilkington at gmail.com, llvm-bugs at lists.llvm.org,
richard-llvm at metafoo.co.uk
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 : https://godbolt.org/z/gHf9YZ
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20191215/be8c1f02/attachment.html>
More information about the llvm-bugs
mailing list