On Sun, 7 Dec 2025, Egas Ribeiro wrote: > When checking a deleted explicit specialization in a SFINAE context, > we were incorrectly selecting a partial specialization because > resolve_nondeduced_context was calling mark_used. But resolving an > overload to a single function (per DR 115) does not constitute ODR-use, > so mark_used shouldn't be called there.
Thanks, looks good! Pushed as r16-5967 (with a short note of how this change impacts convert_to_void to the commit msg for my sake :)) > > PR c++/119343 > > gcc/cp/ChangeLog: > > * pt.cc (resolve_nondeduced_context): Remove mark_used call. > > gcc/testsuite/ChangeLog: > > * g++.dg/template/sfinae-deleted-pr119343.C: New test. > > Signed-off-by: Egas Ribeiro <[email protected]> > --- > gcc/cp/pt.cc | 2 -- > .../g++.dg/template/sfinae-deleted-pr119343.C | 31 +++++++++++++++++++ > 2 files changed, 31 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 8498730b6e4..a9b311be9ac 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -24816,8 +24816,6 @@ 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/template/sfinae-deleted-pr119343.C > b/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C > new file mode 100644 > index 00000000000..065ad605637 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C > @@ -0,0 +1,31 @@ > +// { dg-do compile { target c++11 } } > +// PR c++/119343 - No SFINAE for deleted explicit specializations > + > +struct true_type { static constexpr bool value = true; }; > +struct false_type { static constexpr bool value = false; }; > + > +struct X { > + static void f()=delete; > + template<int> static void g(); > +}; > +template<> void X::g<0>()=delete; > +struct Y { > + static void f(); > + template<int> static void g(); > +}; > + > +template<class T,class=void> > +struct has_f : false_type {}; > +template<class T> > +struct has_f<T,decltype(void(T::f))> : true_type {}; > + > +static_assert(!has_f<X>::value, ""); > +static_assert(has_f<Y>::value, ""); > + > +template<class T,class=void> > +struct has_g0 : false_type {}; > +template<class T> > +struct has_g0<T,decltype(void(T::template g<0>))> : true_type {}; > + > +static_assert(!has_g0<X>::value, ""); > +static_assert(has_g0<Y>::value, ""); > -- > 2.52.0 > >
