https://issues.dlang.org/show_bug.cgi?id=13285

          Issue ID: 13285
           Summary: wrong codegen for destructor call of unnamed struct
                    instance on 64 bit environments
           Product: D
           Version: D2
          Hardware: x86_64
                OS: All
            Status: NEW
          Severity: critical
          Priority: P1
         Component: DMD
          Assignee: nob...@puremagic.com
          Reporter: jbl...@jblume.com

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

--

Reply via email to