diff options
author | Marek Polacek <polacek@redhat.com> | 2020-12-10 15:00:58 -0500 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2021-01-05 11:06:41 -0500 |
commit | af362af18f405c34840d820143aa3a94f72fce4d (patch) | |
tree | 8305ce49ab76c5dffda8338f190b617161d4cdda | |
parent | 27aad521570cbc1050ba957c0ee47aed18033dc1 (diff) | |
download | gcc-af362af18f405c34840d820143aa3a94f72fce4d.zip gcc-af362af18f405c34840d820143aa3a94f72fce4d.tar.gz gcc-af362af18f405c34840d820143aa3a94f72fce4d.tar.bz2 |
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.
-rw-r--r-- | gcc/cp/pt.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept61.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/class-deduction76.C | 1 |
3 files changed, 20 insertions, 1 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 062ef85..0d061ad 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -22373,6 +22373,9 @@ resolve_overloaded_unification (tree tparms, --function_depth; } + if (flag_noexcept_type) + maybe_instantiate_noexcept (fn, tf_none); + elem = TREE_TYPE (fn); if (try_one_overload (tparms, targs, tempargs, parm, elem, strict, sub_strict, addr_p, explain_p) diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept61.C b/gcc/testsuite/g++.dg/cpp0x/noexcept61.C new file mode 100644 index 0000000..653cd7e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept61.C @@ -0,0 +1,17 @@ +// PR c++/82099 +// { dg-do compile { target c++11 } } + +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>); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction76.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction76.C index 23bb6e8..a131a38 100644 --- a/gcc/testsuite/g++.dg/cpp1z/class-deduction76.C +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction76.C @@ -1,6 +1,5 @@ // PR c++/90799 // { dg-do compile { target c++17 } } -// { dg-ice "unify" } template<class T> void foo() noexcept(T::value); |