https://gcc.gnu.org/g:bae0ed69e1862add152f1b0618148f931611a9ca

commit r16-5967-gbae0ed69e1862add152f1b0618148f931611a9ca
Author: Egas Ribeiro <[email protected]>
Date:   Sun Dec 7 23:35:00 2025 +0000

    c++: Fix SFINAE for deleted explicit specializations [PR119343]
    
    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.  Instead callers should call
    mark_used or mark_single_function on the result to uniformly handle all
    resolvable overloads (even non-template-id ones).
    
    This turns out to fix the below testcase because it causes convert_to_void
    for void(X::template g<0>) to properly propagate ODR-use failure (due to
    deleted g<0>) and return error_mark_node instead of returning void_node.
    
            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]>
    Reviewed-by: Patrick Palka <[email protected]>

Diff:
---
 gcc/cp/pt.cc                                       |  2 --
 .../g++.dg/template/sfinae-deleted-pr119343.C      | 31 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 8498730b6e43..a9b311be9ac4 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 000000000000..065ad605637f
--- /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, "");

Reply via email to