From 9479da4515f7d019b4ef282d0e21536431c44f71 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 29 Jun 2023 16:10:18 -0400 Subject: [PATCH] c++: NSDMI instantiation during overload resolution [PR110468] Here we find ourselves instantiating the NSDMI for A<1>::m when computing argument conversions during overload resolution, and thus tf_conv is set. The flag causes mark_used for the constructor used in the NSDMI to exit early and not instantiate its noexcept-spec, which eventually leads to an ICE from nothrow_spec_p. This patch fixes this by clearing any special tsubst flags during instantiation of an NSDMI, since the result should be independent of the context that requires the instantiation. PR c++/110468 gcc/cp/ChangeLog: * init.cc (maybe_instantiate_nsdmi_init): Mask out all tsubst flags except for tf_warning_or_error. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept79.C: New test. --- gcc/cp/init.cc | 4 ++++ gcc/testsuite/g++.dg/cpp0x/noexcept79.C | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept79.C diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index af6e30f511e1..ff5014ca5765 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -579,6 +579,10 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain) /* tsubst_decl uses void_node to indicate an uninstantiated DMI. */ if (init == void_node) { + /* Clear any special tsubst flags; the result of NSDMI instantiation + should be independent of the substitution context. */ + complain &= tf_warning_or_error; + init = DECL_INITIAL (DECL_TI_TEMPLATE (member)); location_t expr_loc = cp_expr_loc_or_loc (init, DECL_SOURCE_LOCATION (member)); diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept79.C b/gcc/testsuite/g++.dg/cpp0x/noexcept79.C new file mode 100644 index 000000000000..d1f54d144319 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept79.C @@ -0,0 +1,18 @@ +// PR c++/110468 +// { dg-do compile { target c++11 } } + +template +struct variant { + variant() noexcept(T > 0); +}; + +template +struct A { + variant m = {}; +}; + +struct B { + B(A<1>); +}; + +B b = {{}}; -- 2.47.2