Optimization Error: += operation while mutating the destination on the right hand side
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
gcc-4.8 (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
default optimizations cause issues with this kind of operation:
dingus.rip += doodle(&dingus);
where the call to doodle() mutates dingus.rip
The produced assembly will use stale data and simply overwrite the mutation with the original value. the resulting code simplifies to this pseudo code:
dingus.rip = 0
doodle(&dingus) === dingus->rip = 4; return 0;
dingus.rip = 0 + return value of doodle()
which is not correct, since it should simplify to this
dingus.rip = 0
doodle(&dingus) === dingus->rip = 4; return 0;
dingus.rip = dingus.rip + return value of doodle()
user@hostname:~/$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~
user@hostname:~/$ gcc -o test test.c
user@hostname:~/$ ./test
0
Expected result: 4
test.c
#include <stdio.h>
struct jit {
unsigned long long rip;
};
unsigned int doodle(struct jit * dingus)
{
dingus->rip = 0x4;
return 0;
}
void tryme(void)
{
struct jit dingus;
dingus.rip = 0;
dingus.rip += doodle(&dingus);
printf("%llx\n", dingus.rip);
return;
}
int main(void)
{
tryme();
}
objdump -D -Mintel ./test
000000000040052d <doodle>:
40052d: 55 push rbp
40052e: 48 89 e5 mov rbp,rsp
400531: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi
400535: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
400539: 48 c7 00 04 00 00 00 mov QWORD PTR [rax],0x4
400540: b8 00 00 00 00 mov eax,0x0
400545: 5d pop rbp
400546: c3 ret
0000000000400547 <tryme>:
400547: 55 push rbp
400548: 48 89 e5 mov rbp,rsp
40054b: 53 push rbx
40054c: 48 83 ec 18 sub rsp,0x18
400550: 48 c7 45 e0 00 00 00 mov QWORD PTR [rbp-0x20],0x0
400557: 00
400558: 48 8b 5d e0 mov rbx,QWORD PTR [rbp-0x20]
40055c: 48 8d 45 e0 lea rax,[rbp-0x20]
400560: 48 89 c7 mov rdi,rax
400563: e8 c5 ff ff ff call 40052d <doodle>
400568: 89 c0 mov eax,eax
40056a: 48 01 d8 add rax,rbx
40056d: 48 89 45 e0 mov QWORD PTR [rbp-0x20],rax
400571: 48 8b 45 e0 mov rax,QWORD PTR [rbp-0x20]
400575: 48 89 c6 mov rsi,rax
400578: bf 24 06 40 00 mov edi,0x400624
40057d: b8 00 00 00 00 mov eax,0x0
400582: e8 89 fe ff ff call 400410 <printf@plt>
400587: 90 nop
400588: 48 83 c4 18 add rsp,0x18
40058c: 5b pop rbx
40058d: 5d pop rbp
40058e: c3 ret
000000000040058f <main>:
40058f: 55 push rbp
400590: 48 89 e5 mov rbp,rsp
400593: e8 af ff ff ff call 400547 <tryme>
400598: 5d pop rbp
400599: c3 ret
40059a: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0]