From: Patrick Palka Date: Thu, 29 Jun 2023 20:10:18 +0000 (-0400) Subject: c++: NSDMI instantiation during overload resolution [PR110468] X-Git-Tag: basepoints/gcc-15~7940 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9479da4515f7d019b4ef282d0e21536431c44f71;p=thirdparty%2Fgcc.git 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. --- 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 = {{}};