www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 17220] New: invalid code with -m32 -inline and struct that's

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

          Issue ID: 17220
           Summary: invalid code with -m32 -inline and struct that's 4x
                    the size of an assigned enum value
           Product: D
           Version: D2
          Hardware: x86
                OS: Linux
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: code dawg.eu

cat > bug.d << CODE
void emitArithInstruction2(BCValue lhs)
{
    if (lhs.type != BCTypeEnum.i32) // type get's overwritten
        assert(0);
}

enum BCTypeEnum : ubyte
{
    Undef,
    i32 = 8, // value must be >= 8
}

struct BCValue // size must be 4 x BCTypeEnum.i32
{
    BCTypeEnum type; // position doesn't matter
    ubyte[4 * BCTypeEnum.i32 - type.sizeof] more;
}
static assert(BCValue.sizeof == 4 * BCTypeEnum.i32);

BCValue i32()
{
    BCValue result; // must be default 0 initialized
    result.type = BCTypeEnum.i32; // set value
    return result;
}

void main()
{
    auto val = i32();
    emitArithInstruction2(val);
}
CODE
dmd -m32 -inline -run bug
----
        mov     cl, 8                                   ; 0806B698 _ B1, 08
        mov     byte ptr [ebp-40H], cl                  ; 0806B69A _ 88. 4D, C0
        lea     esi, [ebp-40H]                          ; 0806B69D _ 8D. 75, C0
        lea     edi, [ebp-20H]                          ; 0806B6A0 _ 8D. 7D, E0
        cmp     byte ptr [ebp-20H], 8                   ; 0806B6A3 _ 80. 7D,
E0, 08
        jz      ?_0170                                  ; 0806B6A7 _ 74, 07
        mov     al, 4                                   ; 0806B6A9 _ B0, 04
        call    _D3bug8__assertFiZv                     ; 0806B6AB _ E8,
00000028
----

The cmp instruction uses a wrong memory location for the struct.

----
Same with i32 = 10 and BCValue.sizeof == 40, so it's not dependent on 32 size
of the struct, but below 32-byte struct initialization is done differently (and
the bug vanishes).

        mov     cl, 10                                  ; 0806B698 _ B1, 0A
        mov     byte ptr [ebp-58H], cl                  ; 0806B69A _ 88. 4D, A8
        lea     esi, [ebp-58H]                          ; 0806B69D _ 8D. 75, A8
        lea     edi, [ebp-28H]                          ; 0806B6A0 _ 8D. 7D, D8
        cmp     byte ptr [ebp-28H], 10                  ; 0806B6A3 _ 80. 7D,
D8, 0A
        jz      ?_0170                                  ; 0806B6A7 _ 74, 07

----

This reduced test-case is not reproducible with -O, but the original bug
instance is.

--
Feb 23