https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107755
Bug ID: 107755 Summary: ICE: in fold_convert_loc, at fold-const.c:2435, with -Wlogical-op, implicit user-defined conversion operator, template function, logical operator, and conditional operator Product: gcc Version: 10.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: pokechu022+gccbugzilla at gmail dot com Target Milestone: --- Created attachment 53928 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53928&action=edit failing code using (!false && (false ? a : b)) A combination of -Wlogical-op, a template function, an implicit user-defined conversion operator, a logical AND or OR operator, and a ternary conditional operator results in an ICE. ``` $ gcc-10 -Wlogical-op -save-temps test.cpp test.cpp: In function ‘bool Bar()’: test.cpp:12:35: internal compiler error: in fold_convert_loc, at fold-const.c:2435 12 | return (!false && (false ? a : b)); | ^ 0x7f08a2bf4082 __libc_start_main ../csu/libc-start.c:308 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <file:///usr/share/doc/gcc-10/README.Bugs> for instructions. $ gcc-10 -v Using built-in specs. COLLECT_GCC=gcc-10 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --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 --enable-libphobos-checking=release --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=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04) ``` I tested at https://godbolt.org/z/574Wq1Ws5 and found that this issue was not present in 4.7.4 and is present in 4.8.1, 12.2, and trunk. Here's the output on trunk from compiler explorer, for convenience: ``` Using built-in specs. COLLECT_GCC=/opt/compiler-explorer/gcc-snapshot/bin/g++ Target: x86_64-linux-gnu Configured with: ../gcc-trunk-20221118/configure --prefix=/opt/compiler-explorer/gcc-build/staging --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-bootstrap --enable-multiarch --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --enable-clocale=gnu --enable-languages=c,c++,fortran,ada,objc,obj-c++,d --enable-ld=yes --enable-gold=yes --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix --with-pkgversion=Compiler-Explorer-Build-gcc-7b3b2f50953c5143d4b14b59d322d8a793f411dd-binutils-2.38 --enable-libstdcxx-backtrace=yes Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.0.0 20221117 (experimental) (Compiler-Explorer-Build-gcc-7b3b2f50953c5143d4b14b59d322d8a793f411dd-binutils-2.38) COLLECT_GCC_OPTIONS='-fdiagnostics-color=always' '-g' '-o' '/app/output.s' '-masm=intel' '-S' '-Wlogical-op' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' '/app/' /opt/compiler-explorer/gcc-trunk-20221118/bin/../libexec/gcc/x86_64-linux-gnu/13.0.0/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -iprefix /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/ -D_GNU_SOURCE <source> -quiet -dumpdir /app/ -dumpbase output.cpp -dumpbase-ext .cpp -masm=intel -mtune=generic -march=x86-64 -g -Wlogical-op -version -fdiagnostics-color=always -o /app/output.s GNU C++17 (Compiler-Explorer-Build-gcc-7b3b2f50953c5143d4b14b59d322d8a793f411dd-binutils-2.38) version 13.0.0 20221117 (experimental) (x86_64-linux-gnu) compiled by GNU C version 9.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 ignoring nonexistent directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../x86_64-linux-gnu/include" ignoring duplicate directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0" ignoring duplicate directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/x86_64-linux-gnu" ignoring duplicate directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/backward" ignoring duplicate directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.0.0/include" ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring duplicate directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.0.0/include-fixed/x86_64-linux-gnu" ignoring duplicate directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.0.0/include-fixed" ignoring nonexistent directory "/opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../x86_64-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0 /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/x86_64-linux-gnu /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/backward /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/include /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/include-fixed/x86_64-linux-gnu /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/x86_64-linux-gnu/13.0.0/include-fixed /usr/local/include /opt/compiler-explorer/gcc-trunk-20221118/bin/../lib/gcc/../../include /usr/include/x86_64-linux-gnu /usr/include End of search list. GNU C++17 (Compiler-Explorer-Build-gcc-7b3b2f50953c5143d4b14b59d322d8a793f411dd-binutils-2.38) version 13.0.0 20221117 (experimental) (x86_64-linux-gnu) compiled by GNU C version 9.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: d17bd4a13b030ab0955e667094fe2b0e <source>: In function 'bool Bar()': <source>:12:35: internal compiler error: in fold_convert_loc, at fold-const.cc:2495 12 | return (!false && (false ? a : b)); | ^ 0x23ac0ce internal_error(char const*, ...) ???:0 0xaaf7fc fancy_abort(char const*, int, char const*) ???:0 0xfb89a1 fold_binary_loc(unsigned int, tree_code, tree_node*, tree_node*, tree_node*) ???:0 0xfc093d fold_build2_loc(unsigned int, tree_code, tree_node*, tree_node*, tree_node*) ???:0 0xfcc891 build_range_check(unsigned int, tree_node*, tree_node*, int, tree_node*, tree_node*) ???:0 0xfcc857 build_range_check(unsigned int, tree_node*, tree_node*, int, tree_node*, tree_node*) ???:0 0xdfe839 warn_logical_operator(unsigned int, tree_code, tree_node*, tree_code, tree_node*, tree_code, tree_node*) ???:0 0xae1b92 build_new_op(op_location_t const&, tree_code, int, tree_node*, tree_node*, tree_node*, tree_node*, tree_node**, int) ???:0 0xd42852 build_x_binary_op(op_location_t const&, tree_code, tree_node*, tree_code, tree_node*, tree_code, tree_node*, tree_node**, int) ???:0 0xc8e277 c_parse_file() ???:0 0xdd7a09 c_common_parse_file() ???:0 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. Compiler returned: 1 ``` A few variants that also trigger the same ICE. The first operand to the ternary operator can be anything (false, true, a bool parameter, etc.). The logical operator can be either || or &&, and the ternary operator can be on either side of it. The other operand of the logical operator can be a bool parameter or !false or !true (but using false or true without a NOT avoids the ICE, probably due to a separate optimisation). The function containing the ternary operator must be a template, even if the template parameters are not used. The second and third operands to the ternary operator must be of different types and must use an implicit user-defined conversion operator. In my example, I compared a bool to a type implicitly convertible to bool, but this also happens with int + implicit conversion to bool, int + implicit conversion to int, two distinct types implicitly convertible to bool, two types implicitly convertible to int, etc. It does not happen if the same type (including template parameters) is used for both operands, nor if no user-defined conversion operator is involved (e.g. int + bool). This issue was originally found at https://github.com/dolphin-emu/dolphin/pull/11289.