https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93359
Bug ID: 93359 Summary: Miscompile (loop check omitted) in function with missing return statement Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: matthijs at stdin dot nl Target Milestone: --- I came across a miscompile, where a missing return statement in a function resulted in a simple for loop never terminating. I originally found this in an STM32 ARM Arduino environment, but managed to reduce this to just a few lines of code and found that it also occurs on x86_64. Here's the testcase: matthijs@grubby:~$ cat foo.cpp #include <stdint.h> volatile uint8_t *REG = 0x0; uint8_t foo() { for (int i = 0; i < 16; i++) *REG = i; } int main() { foo(); } I used a volatile "register" write here just to have something in the loop that will not be optimized away, I originally had actual code in there. Compiling this results in a loop that never terminates: matthijs@grubby:~$ gcc-8 -Os -c foo.cpp foo.cpp: In function ‘uint8_t foo()’: foo.cpp:8:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ matthijs@grubby:~$ objdump -S foo.o foo.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <_Z3foov>: 0: 31 c0 xor %eax,%eax 2: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 9 <_Z3foov+0x9> 9: 88 02 mov %al,(%rdx) b: ff c0 inc %eax d: eb f3 jmp 2 <_Z3foov+0x2> Disassembly of section .text.startup: 0000000000000000 <main>: 0: e8 00 00 00 00 callq 5 <main+0x5> I get identical output on gcc 9, but gcc 7 produces code as expected: matthijs@grubby:~$ gcc-7 -Os -c foo.cpp matthijs@grubby:~$ objdump -S foo.o foo.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <_Z3foov>: 0: 31 c0 xor %eax,%eax 2: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 9 <_Z3foov+0x9> 9: 88 02 mov %al,(%rdx) b: ff c0 inc %eax d: 83 f8 10 cmp $0x10,%eax 10: 75 f0 jne 2 <_Z3foov+0x2> 12: c3 retq Disassembly of section .text.startup: 0000000000000000 <main>: 0: e8 00 00 00 00 callq 5 <main+0x5> 5: 31 c0 xor %eax,%eax 7: c3 retq Also, running with -O0 produces working code: matthijs@grubby:~$ gcc-8 -O0 -c foo.cpp foo.cpp: In function ‘uint8_t foo()’: foo.cpp:8:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ matthijs@grubby:~$ objdump -S foo.o foo.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <_Z3foov>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) b: 83 7d fc 0f cmpl $0xf,-0x4(%rbp) f: 7f 12 jg 23 <_Z3foov+0x23> 11: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 18 <_Z3foov+0x18> 18: 8b 55 fc mov -0x4(%rbp),%edx 1b: 88 10 mov %dl,(%rax) 1d: 83 45 fc 01 addl $0x1,-0x4(%rbp) 21: eb e8 jmp b <_Z3foov+0xb> 23: 90 nop 24: 5d pop %rbp 25: c3 retq 0000000000000026 <main>: 26: 55 push %rbp 27: 48 89 e5 mov %rsp,%rbp 2a: e8 00 00 00 00 callq 2f <main+0x9> 2f: b8 00 00 00 00 mov $0x0,%eax 34: 5d pop %rbp 35: c3 retq This seems C++-specific, when I rename foo.cpp to foo.c and compiler, it produces output as expected. Here's the compiler versions I used, these are just plain Ubuntu x86_64 version: matthijs@grubby:~$ gcc-7 -v Using built-in specs. COLLECT_GCC=gcc-7 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.4.0-8ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 7.4.0 (Ubuntu 7.4.0-8ubuntu1) matthijs@grubby:~$ gcc-8 -v Using built-in specs. COLLECT_GCC=gcc-8 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.3.0-6ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1) matthijs@grubby:~$ gcc-9 -v Using built-in specs. COLLECT_GCC=gcc-9 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.1.0-2ubuntu2~19.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 9.1.0 (Ubuntu 9.1.0-2ubuntu2~19.04) This seems optimization-related, so I guessed the component should be tree-optimization or rtl-optimization, but I had no clue which, so I just picked one.