https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80421

--- Comment #2 from Ivan Johnson <ivan_j_johnson at msn dot com> ---
GCC seems to be dispatching to the wrong case in a switch-statement in the
attached source.  To see the problem, examine the first function in the
attached C file, which is copied below:

    uint32_t to_cigar_int (char op_letter)
    {
        printf("op_letter %c\n", op_letter);
        switch (op_letter) {
            default:
                printf("case default\n");
                if (op_letter == 'D' || op_letter == 'I') {
                    printf("This should never be reached.\n");
                }
                return 0;
            case 'D':
                printf("case 'D'\n");
                return 0;
            case 'I':
                printf("case 'I'\n");
                return 0;
        }
    }

As you can see, control should never reach the printf call for "This should
never be reached" under the default case, because the switch has explicit cases
for 'D' and 'I'.  However, the actual output of the program is as follows:

    op_letter D
    case 'D'
    op_letter M
    case 'I'
    op_letter I
    case default
    This should never be reached.
    op_letter M
    case 'D'
    op_letter D
    case default
    This should never be reached.

Based on the output, the "unreachable printf" call has been executed.  This is
the problem.  It is only seen with optimization turned on.

gcc -v output:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-5 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --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 --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 

Command line used:
gcc -O3 inline_switch.c

Compiler output: none

Reply via email to