https://issues.dlang.org/show_bug.cgi?id=18748
Issue ID: 18748 Summary: bt instruction with immediate offset uses 64-bit variant for 32-bit data Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Keywords: wrong-code Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: ag0ae...@gmail.com ---- int bt_32_imm(in uint* p) { enum bitnum = 1; return ((p[bitnum >> 5] & (1 << (bitnum & 31)))) != 0; } void main() { import core.sys.posix.sys.mman; import core.sys.posix.unistd; // Allocate two pages. immutable sz = 2 * sysconf(_SC_PAGESIZE); auto m = mmap(null, sz, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0); // Discard the higher page. It becomes unreadable. munmap(m + sz / 2, sz / 2); // Try looking at the last 4 bytes of the readable page. uint* p = cast(uint*) (m + sz / 2 - uint.sizeof); bt_32_imm(p); munmap(m, sz / 2); // Free the readable page. } ---- Compile with `-O`. Resulting program segfaults. Generated code for bt_32_imm: ---- 0: 55 push rbp 1: 48 8b ec mov rbp,rsp 4: 48 0f ba 27 01 bt QWORD PTR [rdi],0x1 9: 19 c0 sbb eax,eax b: f7 d8 neg eax d: 5d pop rbp e: c3 ret ---- The bt instruction should be the 32-bit variant (DWORD instead of QWORD). The 64-bit variant tries to load 8 bytes, but only 4 are accessible. --