https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95673
Bug ID: 95673
Summary: Inconsistent optimization behavior when there is a
buffer overflow
Product: gcc
Version: 10.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: regression
Assignee: unassigned at gcc dot gnu.org
Reporter: dn2sp-dev at yahoo dot fr
Target Milestone: ---
Created attachment 48728
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48728&action=edit
Example code
Hello,
I encountered a very strange behavior which i wanted to share with you. I'm not
sure if this is really a bug but the given example file shows a different
behavior in the code generated by -O0/1 and -O2/3.
First in this specific case there is an obvious buffer overflow. (char
data_read[sizeof(DATA)-1];) and this condition is required so the strange
behavior can be observed (if the buffer is not present, the generated code is
correct in both cases).
I also made a test with GCC8 and code behave the same with every -O level
unlike GCC10.
gcc -O0 -g -std=gnu99 test.c -o example; ./example
Output:
> strcmp(MAGIC, MAGIC) == 0
> Comparison is valid
gcc -O3 -g -std=gnu99 test.c -o example; ./example
Output:
> strcmp(MAGIC, MAGIC) == 0
> cmp value is: 0
> This code should not be reached
In the -O2/3 case, the generated assembly code does not include the conditional
jump corresponding to the if (cmp != 0) statement but includes the if ((ret =
fread(&data_read, sizeof(DATA), 1, fd)) != 1) statement.
│ 0x5555555550ee <main+110> callq 0x555555555050 <fread@plt>
│ 0x5555555550f3 <main+115> cmp $0x1,%eax
│ 0x5555555550f6 <main+118> jne 0x555555555164 <main+228>
│ 0x5555555550f8 <main+120> lea 0xf08(%rip),%rdx #
0x555555556007
│ 0x5555555550ff <main+127> mov $0x6,%ecx
│ 0x555555555104 <main+132> mov %r12,%rsi
│ 0x555555555107 <main+135> mov %rdx,%rdi
│ 0x55555555510a <main+138> repz cmpsb %es:(%rdi),%ds:(%rsi)
│ 0x55555555510c <main+140> mov %r12,%rsi
│ 0x55555555510f <main+143> lea 0xef7(%rip),%rdi #
0x55555555600d
│ 0x555555555116 <main+150> seta %bpl
│ 0x55555555511a <main+154> sbb $0x0,%bpl
│ 0x55555555511e <main+158> xor %eax,%eax
│ 0x555555555120 <main+160> movsbl %bpl,%ebp
│ 0x555555555124 <main+164> mov %ebp,%ecx
│ 0x555555555126 <main+166> callq 0x555555555070 <printf@plt>