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

            Bug ID: 77911
           Summary: Comparing function pointers in a constexpr function
                    can produce an error.
           Product: gcc
           Version: 6.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yhueotnk at pokemail dot net
  Target Milestone: ---

Created attachment 39776
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39776&action=edit
Compiler .ii output to reproduce.

I'm attaching two .ii files one that compiles and one one that fails to
compile. There is only one difference between the two files, which is the line:

constexpr unsigned int loc = FindMatchingIdx(&test1, 0);

in the file that compiles, and the file that doesn't compile has:

constexpr unsigned int loc = FindMatchingIdx(&test2, 0);

The difference being &test1 vs &test2.

The code snippet has a constexpr array of function pointers, and then tries to
find a function's index in the array at compile time using the constexpr
function FindMatchingIdx. For some reason the code compiles when
FindMatchingIdx is called with the first element in the array, but fails when
called with any other function in the array.

I've tested this code also on clang and MSVC, where it compiles.

I've used gcc.godbolt.org (https://godbolt.org/g/vunD7M) to test various GCC
builds, and it appears to compile on 4.9.4 but fails on 5.1 and all later
builds.


GCC Version: 6.2.0 20160901 (Ubuntu 6.2.0-3ubuntu11~14.04)
Command line: gcc-6 -v -save-temps -std=c++14 doesnt_compile.cpp


Full gcc output:

swan@pond:/test$ gcc-6 -v -save-temps -std=c++14 doesnt_compile.cpp
Using built-in specs.
COLLECT_GCC=gcc-6
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
6.2.0-3ubuntu11~14.04' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-6 --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=gcc4-compatible --disable-libstdcxx-dual-abi
--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-6-amd64/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-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 6.2.0 20160901 (Ubuntu 6.2.0-3ubuntu11~14.04)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++14' '-mtune=generic'
'-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/6/cc1plus -E -quiet -v -imultiarch
x86_64-linux-gnu -D_GNU_SOURCE doesnt_compile.cpp -mtune=generic -march=x86-64
-std=c++14 -fpch-preprocess -fstack-protector -Wformat -Wformat-security -o
doesnt_compile.ii
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/6"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/6
 /usr/include/x86_64-linux-gnu/c++/6
 /usr/include/c++/6/backward
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++14' '-mtune=generic'
'-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/6/cc1plus -fpreprocessed doesnt_compile.ii
-quiet -dumpbase doesnt_compile.cpp -mtune=generic -march=x86-64 -auxbase
doesnt_compile -std=c++14 -version -fstack-protector -Wformat -Wformat-security
-o doesnt_compile.s
GNU C++14 (Ubuntu 6.2.0-3ubuntu11~14.04) version 6.2.0 20160901
(x86_64-linux-gnu)
        compiled by GNU C version 6.2.0 20160901, GMP version 5.1.3, MPFR
version 3.1.3, MPC version 1.0.1, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++14 (Ubuntu 6.2.0-3ubuntu11~14.04) version 6.2.0 20160901
(x86_64-linux-gnu)
        compiled by GNU C version 6.2.0 20160901, GMP version 5.1.3, MPFR
version 3.1.3, MPC version 1.0.1, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c78046b3d524e42b67cb421e2693df24
doesnt_compile.cpp:14:45:   in constexpr expansion of ‘FindMatchingIdx(test2,
0)’
doesnt_compile.cpp:11:18: error: ‘(test1 != test2)’ is not a constant
expression
     return (work == funcs[idx]) ? (idx) : (FindMatchingIdx(work, idx + 1));
            ~~~~~~^~~~~~~~~~~~~~

Reply via email to