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: nob...@puremagic.com Reporter: c...@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. --