Bug 13285 – wrong codegen for destructor call of unnamed struct instance on 64 bit environments

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2014-08-11T14:55:03Z
Last change time
2019-03-27T22:51:45Z
Keywords
pull
Assigned to
No Owner
Creator
Johannes Blume

Comments

Comment #0 by jblume — 2014-08-11T14:55:03Z
On both Windows and Linux the 64 bit calling convention demands that the stack pointer contains an address aligned to 16 bytes when calling a function. Directly after the CALL instruction, the alignment must be shifted by 8 bytes because of the caller address on the stack. In the following situation, DMD emits wrong code for the caller of the destructor belonging to the unnamed struct instance created by "S()". This happens in both v2.066.0-rc2 and v2.065.0, so it is not a recent regression. struct S { ~this() { ulong stackPtr = void; asm { naked; mov stackPtr, RSP; } // check if stack is misaligned by 8 bytes like it is supposed to be if (stackPtr % 16 != 8) asm { int 3; }; asm { ret; } } } void main() { S s; // correct alignment of RSP when calling ~this() S(); // incorrect alignment } I have used INT3 instead of an assert because the code generating the exception is already affected by the misaligned stack on my system. Here you can compare the incorrect codegen on Win64 for "S().~this()" (coming first) and the correct codegen for "s.~this()" afterwards. Note the missing adjustment to RSP by 8 around the first CALL in the first case. This causes the second CALL to be executed with a misaligned stack. Incorrect for S(): ================== 00007FF70C63109E E8 02 00 00 00 call D main+25h (07FF70C6310A5h) 00007FF70C6310A3 EB 12 jmp D main+37h (07FF70C6310B7h) 00007FF70C6310A5 48 8D 4D F9 lea rcx,[__sl2] 00007FF70C6310A9 48 83 EC 20 sub rsp,20h 00007FF70C6310AD E8 4E FF FF FF call main.S.~this 00007FF70C6310B2 48 83 C4 20 add rsp,20h 00007FF70C6310B6 C3 ret Correct for S s: ================ 00007FF70C6310B7 48 83 EC 08 sub rsp,8 00007FF70C6310BB E8 06 00 00 00 call D main+46h (07FF70C6310C6h) 00007FF70C6310C0 48 83 C4 08 add rsp,8 00007FF70C6310C4 EB 12 jmp D main+58h (07FF70C6310D8h) 00007FF70C6310C6 48 8D 4D F8 lea rcx,[s] 00007FF70C6310CA 48 83 EC 20 sub rsp,20h 00007FF70C6310CE E8 2D FF FF FF call main.S.~this 00007FF70C6310D3 48 83 C4 20 add rsp,20h 00007FF70C6310D7 C3 ret
Comment #1 by dlang-bot — 2019-03-24T20:03:43Z
@rainers created dlang/dmd pull request #9485 "fix Issue 13285 - wrong codegen for destructor call of unnamed struct…" fixing this issue: - fix Issue 13285 - wrong codegen for destructor call of unnamed struct instance on 64 bit environments stack alignment is not coupled with -fPIC https://github.com/dlang/dmd/pull/9485
Comment #2 by dlang-bot — 2019-03-27T22:51:45Z
dlang/dmd pull request #9485 "fix Issue 13285 - wrong codegen for destructor call of unnamed struct…" was merged into stable: - eda7170d3f3b97698391cfa35944098ce821848a by Rainer Schuetze: fix Issue 13285 - wrong codegen for destructor call of unnamed struct instance on 64 bit environments stack alignment is not coupled with -fPIC https://github.com/dlang/dmd/pull/9485