Bug 82099 - internal compiler error: in type_throw_all_p, at cp/except.c:1186 when using a function pointer for templated predicate
Summary: internal compiler error: in type_throw_all_p, at cp/except.c:1186 when using ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.1.0
: P3 normal
Target Milestone: ---
Assignee: Marek Polacek
URL:
Keywords: ice-on-valid-code
: 94525 97773 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-09-04 15:29 UTC by Björn Schäpers
Modified: 2021-01-28 15:38 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-04-13 00:00:00


Attachments
The test file. (256 bytes, text/x-csrc)
2017-09-04 15:29 UTC, Björn Schäpers
Details
The preprocessed test file. (90.49 KB, text/plain)
2017-09-04 15:31 UTC, Björn Schäpers
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Björn Schäpers 2017-09-04 15:29:56 UTC
Created attachment 42116 [details]
The test file.

Trying to use a function pointer as predicate, e.g. in std::equal results in the following error:

$ g++ test.cpp -std=c++1z -save-temps -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=E:/MinGW64/bin/../libexec/gcc/x86_64-w64-mingw32/7.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-7.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw710/x86_64-710-posix-seh-rt_v5-rev2/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev2, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev2/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev2/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev2/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw710/x86_64-710-posix-seh-rt_v5-rev2/mingw64/opt/lib -L/c/mingw710/prerequisites/x86_64-zlib-static/lib -L/c/mingw710/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 7.1.0 (x86_64-posix-seh-rev2, Built by MinGW-W64 project) 
COLLECT_GCC_OPTIONS='-std=c++1z' '-save-temps' '-v' '-shared-libgcc' '-mtune=core2' '-march=nocona'
 E:/MinGW64/bin/../libexec/gcc/x86_64-w64-mingw32/7.1.0/cc1plus.exe -E -quiet -v -iprefix E:/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/7.1.0/ -D_REENTRANT test.cpp -mtune=core2 -march=nocona -std=c++1z -fpch-preprocess -o test.ii
ignoring duplicate directory "E:/MinGW64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++"
ignoring duplicate directory "E:/MinGW64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++/x86_64-w64-mingw32"
ignoring duplicate directory "E:/MinGW64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++/backward"
ignoring duplicate directory "E:/MinGW64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/7.1.0/include"
ignoring nonexistent directory "C:/mingw710/x86_64-710-posix-seh-rt_v5-rev2/mingw64C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.1.0/../../../../include"
ignoring duplicate directory "E:/MinGW64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/7.1.0/include-fixed"
ignoring duplicate directory "E:/MinGW64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/7.1.0/../../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "C:/mingw710/x86_64-710-posix-seh-rt_v5-rev2/mingw64/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
 E:/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++
 E:/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++/x86_64-w64-mingw32
 E:/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/7.1.0/include/c++/backward
 E:/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/7.1.0/include
 E:/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/7.1.0/include-fixed
 E:/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/7.1.0/../../../../x86_64-w64-mingw32/include
End of search list.
COLLECT_GCC_OPTIONS='-std=c++1z' '-save-temps' '-v' '-shared-libgcc' '-mtune=core2' '-march=nocona'
 E:/MinGW64/bin/../libexec/gcc/x86_64-w64-mingw32/7.1.0/cc1plus.exe -fpreprocessed test.ii -quiet -dumpbase test.cpp -mtune=core2 -march=nocona -auxbase test -std=c++1z -version -o test.s
GNU C++14 (x86_64-posix-seh-rev2, Built by MinGW-W64 project) version 7.1.0 (x86_64-w64-mingw32)
	compiled by GNU C version 7.1.0, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.16.1-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++14 (x86_64-posix-seh-rev2, Built by MinGW-W64 project) version 7.1.0 (x86_64-w64-mingw32)
	compiled by GNU C version 7.1.0, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.16.1-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c3bcadf019df782eccf0dceb06ec4054
test.cpp: In function 'int main()':
test.cpp:14:69: internal compiler error: in type_throw_all_p, at cp/except.c:1186
     return std::equal(a.begin(), a.end(), a.begin(), equal<int, int>); //Also fails
                                                                     ^
libbacktrace could not find executable to open
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://sourceforge.net/projects/mingw-w64> for instructions.

Tested on MinGW 7.1, and 7.1 and 7.2 on http://gcc.godbolt.org see https://godbolt.org/g/M6FHp1
Comment 1 Björn Schäpers 2017-09-04 15:31:08 UTC
Created attachment 42117 [details]
The preprocessed test file.
Comment 2 Jakub Jelinek 2017-09-04 16:25:34 UTC
Reduced testcase (fails with all of -std=c++{11,14,17}, just the ICE is different with c++17):
template <typename T, typename U>
void bar (T x, U u)
{
  u (x);
}

template <typename T>
void baz (T t) noexcept (noexcept (t));

void
foo (int x)
{
  bar (x, baz<int>);
}
Comment 3 Jakub Jelinek 2017-09-04 16:28:52 UTC
Started to ICE with r160298 or so (when noexcept has been implemented).
Comment 4 Jakub Jelinek 2017-09-04 16:44:52 UTC
Slightly adjusted testcase that better matches what the original had:

template <typename T, typename U>
void bar (T &x, T &y, U u)
{
  u (x, y);
}

template <typename T>
void baz (T &x, T &y) noexcept (noexcept (x == y));

void
foo (int x, int y)
{
  bar (x, y, baz<int>);
}

The ICE is always because there is a deferred throw/noexcept spec when we assert that it is not deferred.
Comment 5 Volker Reichelt 2018-04-13 19:15:17 UTC
On trunk (GCC 8) the testcases of comment #2 and comment #4 only crash with -std=c++17, but don't crash with -std=c++11 or -std=c++14.
Comment 6 Ed Catmur 2020-04-02 16:31:13 UTC
Workaround: force computation of noexcept of predicate before it is required:

    noexcept(+baz<int>);

or simply

    baz<int>;
Comment 7 Marek Polacek 2020-04-07 21:24:27 UTC
*** Bug 94525 has been marked as a duplicate of this bug. ***
Comment 8 Jonathan Wakely 2020-11-10 10:37:18 UTC
*** Bug 97773 has been marked as a duplicate of this bug. ***
Comment 9 Marek Polacek 2020-12-10 03:27:11 UTC
I have a patch.
Comment 10 GCC Commits 2021-01-05 16:08:17 UTC
The master branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:af362af18f405c34840d820143aa3a94f72fce4d

commit r11-6476-gaf362af18f405c34840d820143aa3a94f72fce4d
Author: Marek Polacek <polacek@redhat.com>
Date:   Thu Dec 10 15:00:58 2020 -0500

    c++: ICE with deferred noexcept when deducing targs [PR82099]
    
    In this test we ICE in type_throw_all_p because it got a deferred
    noexcept which it shouldn't.  Here's the story:
    
    In noexcept61.C, we call bar, so we perform overload resolution.  When
    adding the (only) candidate, we need to deduce template arguments, so
    call fn_type_unification as usually.  That deduces U to
    
      void (*) (int &, int &)
    
    which is correct, but its noexcept-spec is deferred_noexcept.  Then
    we call add_function_candidate (bar), wherein we try to create an
    implicit conversion sequence for every argument.  Since baz<int> is
    of unknown type, we instantiate_type it; it is a TEMPLATE_ID_EXPR
    so that calls resolve_address_of_overloaded_function.  But we crash
    there, because target_type contains the deferred_noexcept.
    
    So we need to maybe_instantiate_noexcept before we can compare types.
    resolve_overloaded_unification seemed like the appropriate spot, now
    fn_type_unification produces the function type with its noexcept-spec
    instantiated.  This shouldn't go against CWG 1330 because here we
    really need to instantiate the noexcept-spec.
    
    This also fixes class-deduction76.C, a dg-ice test I recently added,
    therefore this fix also fixes c++/90799, yay.
    
    gcc/cp/ChangeLog:
    
            PR c++/82099
            * pt.c (resolve_overloaded_unification): Call
            maybe_instantiate_noexcept after instantiating the function
            decl.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/82099
            * g++.dg/cpp1z/class-deduction76.C: Remove dg-ice.
            * g++.dg/cpp0x/noexcept61.C: New test.
Comment 11 GCC Commits 2021-01-05 21:33:55 UTC
The releases/gcc-10 branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:ff22b4e8d0613170601d28eec9462ea31147c7c7

commit r10-9209-gff22b4e8d0613170601d28eec9462ea31147c7c7
Author: Marek Polacek <polacek@redhat.com>
Date:   Tue Jan 5 16:33:07 2021 -0500

    c++: ICE with deferred noexcept when deducing targs [PR82099]
    
    In this test we ICE in type_throw_all_p because it got a deferred
    noexcept which it shouldn't.  Here's the story:
    
    In noexcept61.C, we call bar, so we perform overload resolution.  When
    adding the (only) candidate, we need to deduce template arguments, so
    call fn_type_unification as usually.  That deduces U to
    
      void (*) (int &, int &)
    
    which is correct, but its noexcept-spec is deferred_noexcept.  Then
    we call add_function_candidate (bar), wherein we try to create an
    implicit conversion sequence for every argument.  Since baz<int> is
    of unknown type, we instantiate_type it; it is a TEMPLATE_ID_EXPR
    so that calls resolve_address_of_overloaded_function.  But we crash
    there, because target_type contains the deferred_noexcept.
    
    So we need to maybe_instantiate_noexcept before we can compare types.
    resolve_overloaded_unification seemed like the appropriate spot, now
    fn_type_unification produces the function type with its noexcept-spec
    instantiated.  This shouldn't go against CWG 1330 because here we
    really need to instantiate the noexcept-spec.
    
    This also fixes class-deduction76.C, a dg-ice test I recently added,
    therefore this fix also fixes c++/90799, yay.
    
    gcc/cp/ChangeLog:
    
            PR c++/82099
            * pt.c (resolve_overloaded_unification): Call
            maybe_instantiate_noexcept after instantiating the function
            decl.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/82099
            * g++.dg/cpp0x/noexcept61.C: New test.
Comment 12 Marek Polacek 2021-01-05 21:37:30 UTC
Fixed.