[Issue 21778] New: Win64: Access-violation for -release -checkaction=context

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Mar 28 23:18:49 UTC 2021


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

          Issue ID: 21778
           Summary: Win64: Access-violation for -release
                    -checkaction=context
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Windows
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: moonlightsentinel at disroot.org

The following code crashes with an access violation when compiled with -release
-checkaction=context (the latter is probably only relevant because it causes a
hidden temporary).

----------------------------------------------------------------------------

float getreal_rcx(cfloat z)
{
    return z.re;
}

float getimag_rcx(cfloat z)
{
    return z.im;
}

extern(C) void main()
{
    cfloat[1] A;
    float[1] B;
    int i;
    A = 2 + 4i;

    assert(getreal_rcx(A[i] * B[i]));

    getimag_rcx(A[i] * B[i]);            // <== Access Violation
}


// Required declarations copied from druntime

alias string = immutable(char)[];
alias size_t = long;

// (Empty) hook for -checkaction=context
string _d_assert_fail(A)(const scope string op, auto ref const scope A a)
{
    static immutable string msg = "Hello, world!";
    return msg;
}

// Required because of the static arrays
extern(C) long *_memset64(long *p, long value, size_t count)
{
    long *pstart = p;
    long *ptop;

    for (ptop = &p[count]; p < ptop; p++)
        *p = value;
    return pstart;
}

extern(C) float *_memsetFloat(float *p, float value, size_t count)
{
    float *pstart = p;
    float *ptop;

    for (ptop = &p[count]; p < ptop; p++)
        *p = value;
    return pstart;
}

----------------------------------------------------------------------------

Compiled with:
dmd -conf= -defaultlib= -release -checkaction=context -g -m64 .\object.d

Debugging with VS yields:

Exception thrown at 0x00007FF75E1C1110 in object.exe:
0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.


Output of -vcg-ast:

----------------------------------------------------------------------------
import object;

float getreal_rcx(cfloat z)
{
        return cast(float)z;
}

float getimag_rcx(cfloat z)
{
        return cast(ifloat)z;
}

extern (C) extern (C) void main()
{
        cfloat[1] A = (nanF+nanFi);
        float[1] B = nanF;
        int i = 0;
        A[] = (2.0F+4.0Fi);
        (float __assertOp1 = getreal_rcx(A[cast(ulong)i] * B[cast(ulong)i]);) ,
assert(__assertOp1, _d_assert_fail("", __assertOp1));
        getimag_rcx(A[cast(ulong)i] * B[cast(ulong)i]);
}

alias string = immutable(char)[];
alias size_t = long;

string _d_assert_fail(A)(scope const string op, auto ref scope const A a)
{
        static immutable string msg = "Hello, world!";
        return msg;
}

extern (C) extern (C) long* _memset64(long* p, long value, long count)
{
        long* pstart = p;
        long* ptop = null;
        {
                ptop = &p[cast(ulong)count];
                for (; p < ptop; p++)
                {
                        *p = value;
                }
        }
        return pstart;
}

extern (C) extern (C) float* _memsetFloat(float* p, float value, long count)
{
        float* pstart = p;
        float* ptop = null;
        {
                ptop = &p[cast(ulong)count];
                for (; p < ptop; p++)
                {
                        *p = value;
                }
        }
        return pstart;
}

_d_assert_fail!float
{
        pure nothrow @nogc @safe string _d_assert_fail(scope const(string) op,
ref const(float) a)
        {
                static immutable immutable(string) msg = "Hello, world!";
                return msg;
        }

}
----------------------------------------------------------------------------


Disassembly from Visual Studio:


----------------------------------------------------------------------------

--- object.d ---------------------------
float getreal_rcx(cfloat z)
00007FF75E1C1002  mov         ebp,esp  
00007FF75E1C1004  mov         qword ptr [z],rcx  
{
    return z.re;
00007FF75E1C1008  movss       xmm0,dword ptr [z]  
}
00007FF75E1C100D  pop         rbp  
00007FF75E1C100E  ret  
--- No source file
-------------------------------------------------------------
00007FF75E1C100F  int         3  
--- object.d ---------------------------

float getimag_rcx(cfloat z)
00007FF75E1C1010  push        rbp  
00007FF75E1C1011  mov         rbp,rsp  
00007FF75E1C1014  mov         qword ptr [z],rcx  
{
    return z.im;
00007FF75E1C1018  movss       xmm0,dword ptr [rbp+14h]  
}
00007FF75E1C101D  pop         rbp  
00007FF75E1C101E  ret  
--- No source file
-------------------------------------------------------------
00007FF75E1C101F  int         3  
--- object.d ---------------------------

extern(C) void main()
00007FF75E1C1020  push        rbp  
00007FF75E1C1021  mov         rbp,rsp  
00007FF75E1C1024  sub         rsp,50h  
00007FF75E1C1028  push        rbx  
00007FF75E1C1029  push        rsi  
{
    cfloat[1] A;
00007FF75E1C102A  mov         r8d,1  
{
    cfloat[1] A;
00007FF75E1C1030  fld         dword ptr [__xt_z+10h (07FF75E1CE2C0h)]  
00007FF75E1C1036  fld         dword ptr [__xt_z+14h (07FF75E1CE2C4h)]  
00007FF75E1C103C  fstp        dword ptr [rbp-24h]  
00007FF75E1C103F  fstp        dword ptr [rbp-28h]  
00007FF75E1C1042  lea         rax,[rbp-28h]  
00007FF75E1C1046  mov         rdx,qword ptr [rax]  
00007FF75E1C1049  lea         rcx,[A]  
00007FF75E1C104D  sub         rsp,20h  
00007FF75E1C1051  call        object._memset64 (07FF75E1C1140h)  
00007FF75E1C1056  add         rsp,20h  
    float[1] B;
00007FF75E1C105A  mov         r8d,1  
00007FF75E1C1060  movss       xmm0,dword ptr [__xt_z+18h (07FF75E1CE2C8h)]  
00007FF75E1C1068  movss       dword ptr [rbp-1Ch],xmm0  
00007FF75E1C106D  lea         rax,[rbp-1Ch]  
00007FF75E1C1071  movss       xmm1,dword ptr [rax]  
00007FF75E1C1075  lea         rcx,[B]  
00007FF75E1C1079  sub         rsp,20h  
00007FF75E1C107D  movq        rdx,xmm1  
00007FF75E1C1082  call        object._memsetFloat (07FF75E1C11A0h)  
00007FF75E1C1087  add         rsp,20h  
    int i;
00007FF75E1C108B  xor         edx,edx  
00007FF75E1C108D  mov         dword ptr [i],edx  
    A = 2 + 4i;
00007FF75E1C1090  mov         r8d,1  
00007FF75E1C1096  fld         dword ptr [__xt_z+20h (07FF75E1CE2D0h)]  
00007FF75E1C109C  fld         dword ptr [__xt_z+24h (07FF75E1CE2D4h)]  
00007FF75E1C10A2  fstp        dword ptr [rbp-0Ch]  
00007FF75E1C10A5  fstp        dword ptr [rbp-10h]  
00007FF75E1C10A8  lea         rax,[rbp-10h]  
00007FF75E1C10AC  mov         rdx,qword ptr [rax]  
00007FF75E1C10AF  lea         rcx,[A]  
00007FF75E1C10B3  sub         rsp,20h  
00007FF75E1C10B7  call        object._memset64 (07FF75E1C1140h)  
00007FF75E1C10BC  add         rsp,20h  

    assert(getreal_rcx(A[i] * B[i]));
00007FF75E1C10C0  movsxd      rbx,dword ptr [i]  
00007FF75E1C10C4  lea         rsi,[A]  
00007FF75E1C10C8  lea         rax,[rsi+rbx*8]  
00007FF75E1C10CC  fld         dword ptr [rax]  
00007FF75E1C10CE  fld         dword ptr [rax+4]  
00007FF75E1C10D1  lea         rdx,[B]  
00007FF75E1C10D5  lea         rcx,[rdx+rbx*4]  
00007FF75E1C10D9  fld         dword ptr [rcx]  
00007FF75E1C10DB  fmul        st(2),st  
00007FF75E1C10DD  fmulp       st(1),st  
00007FF75E1C10DF  fstp        dword ptr [rbp-3Ch]  
00007FF75E1C10E2  fstp        dword ptr [rbp-40h]  
00007FF75E1C10E5  mov         qword ptr [rbp-50h],rax  
00007FF75E1C10E9  mov         rcx,qword ptr [rbp-40h]  
00007FF75E1C10ED  sub         rsp,20h  
00007FF75E1C10F1  mov         qword ptr [rbp-48h],rcx  
00007FF75E1C10F5  call        object.getreal_rcx (07FF75E1C1000h)  
00007FF75E1C10FA  add         rsp,20h  
00007FF75E1C10FE  movss       dword ptr [__assertOp1],xmm0  

    getimag_rcx(A[i] * B[i]);
00007FF75E1C1103  mov         rbx,qword ptr [rbp-50h]  
00007FF75E1C1107  fld         dword ptr [rbx]  
00007FF75E1C1109  fld         dword ptr [rbx+4]  
00007FF75E1C110C  mov         rsi,qword ptr [rbp-48h]  
00007FF75E1C1110  fld         dword ptr [rsi]                           // <==
Access Violation
00007FF75E1C1112  fmul        st(2),st  
00007FF75E1C1114  fmulp       st(1),st  
00007FF75E1C1116  fstp        dword ptr [rbp-3Ch]  
00007FF75E1C1119  fstp        dword ptr [rbp-40h]  
00007FF75E1C111C  mov         rcx,qword ptr [rbp-40h]  
00007FF75E1C1120  sub         rsp,20h  
00007FF75E1C1124  call        object.getimag_rcx (07FF75E1C1010h)  
00007FF75E1C1129  add         rsp,20h  
}
00007FF75E1C112D  pop         rsi  
00007FF75E1C112E  pop         rbx  
00007FF75E1C112F  mov         rsp,rbp  
00007FF75E1C1132  pop         rbp  
00007FF75E1C1133  ret  
--- No source file
-------------------------------------------------------------
00007FF75E1C1134  int         3  
00007FF75E1C1135  int         3  
00007FF75E1C1136  int         3  
00007FF75E1C1137  int         3  
00007FF75E1C1138  int         3  
00007FF75E1C1139  int         3  
00007FF75E1C113A  int         3  
00007FF75E1C113B  int         3  
00007FF75E1C113C  int         3  
00007FF75E1C113D  int         3  
00007FF75E1C113E  int         3  
00007FF75E1C113F  int         3  
--- object.d ---------------------------

alias string = immutable(char)[];
alias size_t = long;

string _d_assert_fail(A)(const scope string op, auto ref const scope A a)
{
    static immutable string msg = "Hello, world!";
    return msg;
}



extern(C) long *_memset64(long *p, long value, size_t count)
00007FF75E1C1140  push        rbp  
00007FF75E1C1141  mov         rbp,rsp  
00007FF75E1C1144  sub         rsp,10h  
00007FF75E1C1148  push        rbx  
00007FF75E1C1149  push        rsi  
00007FF75E1C114A  mov         qword ptr [p],rcx  
00007FF75E1C114E  mov         qword ptr [value],rdx  
00007FF75E1C1152  mov         qword ptr [count],r8  
{
    long *pstart = p;
00007FF75E1C1156  mov         rax,qword ptr [p]  
{
    long *pstart = p;
00007FF75E1C115A  mov         qword ptr [pstart],rax  
    long *ptop;
00007FF75E1C115E  mov         qword ptr [ptop],0  

    for (ptop = &p[count]; p < ptop; p++)
00007FF75E1C1166  mov         rcx,qword ptr [count]  
00007FF75E1C116A  lea         rdx,[rax+rcx*8]  
00007FF75E1C116E  mov         qword ptr [ptop],rdx  
00007FF75E1C1172  mov         rbx,qword ptr [p]  
00007FF75E1C1176  cmp         rbx,qword ptr [ptop]  
00007FF75E1C117A  jae         object._memset64+4Eh (07FF75E1C118Eh)  
        *p = value;
00007FF75E1C117C  mov         rsi,qword ptr [value]  
00007FF75E1C1180  mov         rax,qword ptr [p]  
00007FF75E1C1184  mov         qword ptr [rax],rsi  

    for (ptop = &p[count]; p < ptop; p++)
00007FF75E1C1187  add         qword ptr [p],8  
00007FF75E1C118C  jmp         object._memset64+32h (07FF75E1C1172h)  
    return pstart;
00007FF75E1C118E  mov         rax,qword ptr [pstart]  
}
00007FF75E1C1192  pop         rsi  
00007FF75E1C1193  pop         rbx  
00007FF75E1C1194  mov         rsp,rbp  
00007FF75E1C1197  pop         rbp  
00007FF75E1C1198  ret  
--- No source file
-------------------------------------------------------------
00007FF75E1C1199  int         3  
00007FF75E1C119A  int         3  
00007FF75E1C119B  int         3  
00007FF75E1C119C  int         3  
00007FF75E1C119D  int         3  
00007FF75E1C119E  int         3  
00007FF75E1C119F  int         3  
--- object.d ---------------------------

extern(C) float *_memsetFloat(float *p, float value, size_t count)
00007FF75E1C11A0  push        rbp  
00007FF75E1C11A1  mov         rbp,rsp  
00007FF75E1C11A4  sub         rsp,10h  
00007FF75E1C11A8  push        rbx  
00007FF75E1C11A9  mov         qword ptr [p],rcx  
00007FF75E1C11AD  movss       dword ptr [value],xmm1  
00007FF75E1C11B2  mov         qword ptr [count],r8  
{
    float *pstart = p;
00007FF75E1C11B6  mov         rax,qword ptr [p]  
00007FF75E1C11BA  mov         qword ptr [pstart],rax  
    float *ptop;
00007FF75E1C11BE  mov         qword ptr [ptop],0  

    for (ptop = &p[count]; p < ptop; p++)
00007FF75E1C11C6  mov         rcx,qword ptr [count]  
00007FF75E1C11CA  lea         rdx,[rax+rcx*4]  
00007FF75E1C11CE  mov         qword ptr [ptop],rdx  
00007FF75E1C11D2  mov         rbx,qword ptr [p]  
00007FF75E1C11D6  cmp         rbx,qword ptr [ptop]  
00007FF75E1C11DA  jae         object._memsetFloat+50h (07FF75E1C11F0h)  
        *p = value;
00007FF75E1C11DC  movss       xmm0,dword ptr [value]  
00007FF75E1C11E1  mov         rax,qword ptr [p]  
00007FF75E1C11E5  movss       dword ptr [rax],xmm0  

    for (ptop = &p[count]; p < ptop; p++)
00007FF75E1C11E9  add         qword ptr [p],4  
00007FF75E1C11EE  jmp         object._memsetFloat+32h (07FF75E1C11D2h)  
    return pstart;
00007FF75E1C11F0  mov         rax,qword ptr [pstart]  
}
00007FF75E1C11F4  pop         rbx  
00007FF75E1C11F5  mov         rsp,rbp  
00007FF75E1C11F8  pop         rbp  
00007FF75E1C11F9  ret 

----------------------------------------------------------------------------

--


More information about the Digitalmars-d-bugs mailing list