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.

Reply via email to