https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64037
Bug ID: 64037
Summary: Miscompilation with LTO and enum class : char
parameter
Product: gcc
Version: 4.9.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: js at alien8 dot de
Created attachment 34082
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34082&action=edit
Minimal test case
On Linux with the x86-64 target, code that contains a byte-sized enum class as
a function parameter is miscompiled when -Os and -flto is enabled. A minimal
example is attached. I also attached g++ --verbose --version output for both
compilers where this triggers (4.9.1 and 4.9.2).
To reproduce the problem compile the attached source with:
g++ -std=gnu++11 -Os -flto test.cc -o test
Run ./test and you get this output: deadbe02
Expected output: 00000002
The problem boils down to the fact that the third parameter to foo (see below)
is passed in DL (the rest of RDX is not cleared). In the function, no code is
emitted to clear the rest of RDX, but it is obviously assumed to be zero.
enum class X : unsigned char {
V = 2,
};
// noinline and noclone are only there to reduce the example. This
// also triggers without these annotations in larger projects.
void foo(unsigned &out, unsigned a, X b) __attribute__((noinline,noclone));
void foo(unsigned &out, unsigned a, X b)
{
out = static_cast<unsigned>(b);
}
int main()
{
// Load obvious value into EDX
unsigned deadbeef = 0xDEADBEEF;
asm volatile ("" : "+d" (deadbeef));
unsigned out;
foo(out, 2, X::V);
...
0000000000400500 <main>:
400500: 48 83 ec 18 sub rsp,0x18
400504: ba ef be ad de mov edx,0xdeadbeef <- EDX is loaded
with some garbage
400509: 48 8d 7c 24 0c lea rdi,[rsp+0xc]
40050e: b2 02 mov dl,0x2 <- Parameter is
put in DL, without clearing RDX first
400510: be 02 00 00 00 mov esi,0x2
400515: e8 0c 01 00 00 call 400626 <foo(unsigned int&,
unsigned int, X)>
0000000000400626 <foo(unsigned int&, unsigned int, X)>:
400626: 89 17 mov DWORD PTR [rdi],edx <- EDX still
contains remnants of 0xDEADBEEF here!
400628: c3 ret