[Issue 18232] string variable in toString method of Union: invalid code (crash/segfault)
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Jan 12 18:18:22 UTC 2018
https://issues.dlang.org/show_bug.cgi?id=18232
hsteoh at quickfur.ath.cx changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |hsteoh at quickfur.ath.cx
--- Comment #1 from hsteoh at quickfur.ath.cx ---
The crash is caused by wrong codegen for the toString() method. Here's a
comparison of a toString() method for a struct vs. for a union:
Struct code:
--------
struct Jack
{
float f;
int i;
string toString()
{
string s;
return s;
}
}
--------
Generated assembly for Jack.toString:
--------
447dc: 55 push %rbp
447dd: 48 8b ec mov %rsp,%rbp
447e0: 31 c0 xor %eax,%eax
447e2: 31 d2 xor %edx,%edx
447e4: 5d pop %rbp
447e5: c3 retq
--------
As can be easily seen, this basically initializes the string s to have
.ptr=null, .length=0, returned by value in %eax and %edx. This is the correct
behaviour.
Union code (basically the same as the struct code, just change 'struct' to
'union'):
--------
union Jack
{
float f;
int i;
string toString()
{
string s;
return s;
}
}
--------
Generated assembly for Jack.toString:
--------
4471c: 55 push %rbp
4471d: 48 8b ec mov %rsp,%rbp
44720: 48 83 ec 10 sub $0x10,%rsp
44724: 48 8b 55 f8 mov -0x8(%rbp),%rdx
44728: 48 8b 45 f0 mov -0x10(%rbp),%rax
4472c: c9 leaveq
4472d: c3 retq
--------
Here, the 'sub' line appears to be allocating space on the stack for a local
variable, presumeably s. But then it fails to initialize s before loading it
into the return registers %rdx and %rax. I'm assuming that this is probably
why the allocation of the local variable never got elided, as it was in the
struct case -- the optimizer doesn't see the missing initialization of s, so it
cannot elide the loads from the stack.
So it looks like the bug is caused by failure to initialize s when generating
code for a union vs. a struct. Why, though, is a mystery to me, since toString
never actually references `this`, so in theory whether `this` is a struct or
union shouldn't matter.
--
More information about the Digitalmars-d-bugs
mailing list