[gcc r16-9470] c++: resolvedness of resolve_nondeduced_context result [PR126406]
Patrick Palka via Gcc-cvs <[email protected]> Fri, 31 Jul 2026 02:40:43 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:8491b800473971ba1c03e74866273cb8dcaa5edc commit r16-9470-g8491b800473971ba1c03e74866273cb8dcaa5edc Author: Patrick Palka <[email protected]> Date: Thu Jul 30 21:18:38 2026 -0400 c++: resolvedness of resolve_nondeduced_context result [PR126406] In r16-5967-gbae0ed69e1862a we removed the mark_used call from resolve_nondeduced_context under the rationale that it should be the caller's responsiblity to mark_used. Removing the call however now means that resolve_nondeduced_context could return a specialization whose type is not yet fully resolved (i.e. has an uninstantiated noexcept or undeduced return type), and callers that immediately inspect TREE_TYPE of the result (such as standard_conversion and build_conditional_expr) now misbehave. In light of such callers, this patch reverts r16-5967; it's not necessary to fix PR119343 because after r16-6276 convert_to_void now properly propagates an error_mark_node result from resolve_nondeduced_context. PR c++/126406 PR c++/119343 gcc/cp/ChangeLog: * pt.cc (resolve_nondeduced_context): Revert r16-5967 change. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/cond2a.C: New test. * g++.dg/cpp1y/auto-fn67.C: New test. * g++.dg/cpp1z/noexcept-type29.C: New test. Reviewed-by: Jason Merrill <[email protected]> (cherry picked from commit e873aac49eb2b58ae18e05f4150826278bdbb3cb) Diff: --- gcc/cp/pt.cc | 2 ++ gcc/testsuite/g++.dg/cpp0x/cond2a.C | 17 +++++++++++++++++ gcc/testsuite/g++.dg/cpp1y/auto-fn67.C | 11 +++++++++++ gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C | 11 +++++++++++ 4 files changed, 41 insertions(+) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 9d3a972e3002..dd578bef0bb3 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -25452,6 +25452,8 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain) } if (good == 1) { + if (!mark_used (goodfn, complain) && !(complain & tf_error)) + return error_mark_node; expr = goodfn; if (baselink) expr = build_baselink (BASELINK_BINFO (baselink), diff --git a/gcc/testsuite/g++.dg/cpp0x/cond2a.C b/gcc/testsuite/g++.dg/cpp0x/cond2a.C new file mode 100644 index 000000000000..a42e198291b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/cond2a.C @@ -0,0 +1,17 @@ +// PR c++/126406 +// { dg-do compile { target c++14 } } +// A version of cond2.C where f has a deduced return type +// and g is instantiated. + +bool b; + +template < class T > auto f () +{ +} + +template < class T > auto g () -> decltype (b ? f < int > : throw 0) +{ + return b ? f<int> : throw 0; +} + +using type = decltype(g<int>()); diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn67.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn67.C new file mode 100644 index 000000000000..82d74441feec --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn67.C @@ -0,0 +1,11 @@ +// PR c++/126406 +// { dg-do compile { target c++14 } } + +template<class T> auto g(T) { } +static_assert(g<int>, ""); + +template<class T> +struct B { + static auto g(T) { } +}; +static_assert(B<int>::g, ""); diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C new file mode 100644 index 000000000000..51bf87c85fa5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type29.C @@ -0,0 +1,11 @@ +// PR c++/126406 +// { dg-do compile { target c++11 } } + +template<class T> void f(T) noexcept(noexcept(T())) { } +static_assert(f<int>, ""); + +template<class T> +struct A { + static void f(T) noexcept(noexcept(T())) { } +}; +static_assert(A<int>::f, "");