← Back to index
|
Original Bugzilla link
Bug 11663 – incorrect double increment in array assign expression
Status
RESOLVED
Resolution
WORKSFORME
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-12-02T05:30:00Z
Last change time
2014-09-09T15:11:09Z
Keywords
wrong-code
Assigned to
nobody
Creator
john.loughran.colvin
Comments
Comment #0
by john.loughran.colvin — 2013-12-02T05:30:58Z
when boundschecks are enabled: Some expressions of the form a[i++] |= b; generate code for the increment and boundscheck TWICE, with both positioned before both the actual read, modify and write occurs. Hence the wrong memory location is read from and written to, as well as the resulting i being incorrect. The problem doesn't seem to manifest in small code examples so I don't have a test-case, but here's an excerpt from something larger to demonstrate the problem: struct BitBin { private ubyte[] _data; private size_t index; private ubyte bitOffset; void push(T)(T d) { // ........... writeln(index); _data[index++] |= d >> tailLength; writeln(index); //prints previous index + 2 // ........... } disassembly: 15e: 49 8b 7c 24 10 mov rdi,QWORD PTR [r12+0x10] 163: e8 00 00 00 00 call 168 <_D8Huffman26BitBin12__T5push1TmZ5push1MFmmZv+0x168> 164: R_X86_64_PC32 _D3std5stdio14__T7writelnTmZ7writelnFmZv-0x4 168: 4d 8b 7c 24 10 mov r15,QWORD PTR [r12+0x10] 16d: 49 ff c7 inc r15 170: 4d 89 7c 24 10 mov QWORD PTR [r12+0x10],r15 175: 49 ff cf dec r15 178: 4d 3b 3c 24 cmp r15,QWORD PTR [r12] 17c: 72 0a jb 188 <_D8Huffman26BitBin12__T5push1TmZ5push1MFmmZv+0x188> 17e: bf 93 00 00 00 mov edi,0x93 183: e8 00 00 00 00 call 188 <_D8Huffman26BitBin12__T5push1TmZ5push1MFmmZv+0x188> 184: R_X86_64_PC32 _D8Huffman27__arrayZ-0x4 188: 4d 8b 7c 24 10 mov r15,QWORD PTR [r12+0x10] 18d: 49 ff c7 inc r15 190: 4d 89 7c 24 10 mov QWORD PTR [r12+0x10],r15 195: 49 ff cf dec r15 198: 4d 3b 3c 24 cmp r15,QWORD PTR [r12] 19c: 72 0a jb 1a8 <_D8Huffman26BitBin12__T5push1TmZ5push1MFmmZv+0x1a8> 19e: bf 93 00 00 00 mov edi,0x93 1a3: e8 00 00 00 00 call 1a8 <_D8Huffman26BitBin12__T5push1TmZ5push1MFmmZv+0x1a8> 1a4: R_X86_64_PC32 _D8Huffman27__arrayZ-0x4 1a8: 49 8b 4c 24 08 mov rcx,QWORD PTR [r12+0x8] 1ad: 49 03 cf add rcx,r15 1b0: 0f b6 01 movzx eax,BYTE PTR [rcx] 1b3: 48 98 cdqe 1b5: 49 8b d5 mov rdx,r13 1b8: 48 89 8d a0 ff ff ff mov QWORD PTR [rbp-0x60],rcx 1bf: 41 8b ce mov ecx,r14d 1c2: 48 d3 ea shr rdx,cl 1c5: 48 0b c2 or rax,rdx 1c8: 48 8b b5 a0 ff ff ff mov rsi,QWORD PTR [rbp-0x60] 1cf: 88 06 mov BYTE PTR [rsi],al 1d1: 49 8b 7c 24 10 mov rdi,QWORD PTR [r12+0x10] 1d6: e8 00 00 00 00 call 1db <_D8Huffman26BitBin12__T5push1TmZ5push1MFmmZv+0x1db> 1d7: R_X86_64_PC32 _D3std5stdio14__T7writelnTmZ7writelnFmZv-0x4 168 - 183 is the first increment. It is then immediately repeated in 188 - 1a3. The result is that the incremented value of [r12 + 0x10] is used for both the read and write. [r12 + 0x10] itself is incremented twice.
Comment #1
by yebblies — 2014-07-23T16:01:21Z
Without a test case this is very unlikely to get fixed.
Comment #2
by yebblies — 2014-09-09T15:11:09Z
I can't reproduce this.