On 2/27/25 4:51 PM, Patrick Palka wrote:
Tested on x86_64-pc-linux-gnu, does this look OK for stage 1?

Yes.

-- >8 --

The PR68942 fix used the tf_conv flag to disable mark_used when
substituting a FUNCTION_DECL callee of an ADL-enabled call.  In this
slightly more elaborate testcase, we end up prematurely calling
mark_used anyway on the FUNCTION_DECL directly from the CALL_EXPR case
of tsubst_expr during partial instantiation, leading to a bogus "use of
deleted function" error.

This patch fixes the general problem in a more robust way by ensuring
the callee of an ADL-enabled call is wrapped in an OVERLOAD, so that
tsubst_expr leaves it alone.

        PR c++/119034
        PR c++/68942

gcc/cp/ChangeLog:

        * pt.cc (tsubst_expr) <case CALL_EXPR>: Revert PR68942 fix to
        * semantics.cc (finish_call_expr): Ensure the callee of an
        ADL-enabled call is wrapped in an OVERLOAD.

gcc/testsuite/ChangeLog:

        * g++.dg/template/koenig13.C: New test.
---
  gcc/cp/pt.cc                             |  8 +-------
  gcc/cp/semantics.cc                      |  8 ++++++++
  gcc/testsuite/g++.dg/template/koenig13.C | 16 ++++++++++++++++
  3 files changed, 25 insertions(+), 7 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/template/koenig13.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 62d91a2dd15..4b69b26808b 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -21290,13 +21290,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
              /* Avoid error about taking the address of a constructor.  */
              function = TREE_OPERAND (function, 0);
- tsubst_flags_t subcomplain = complain;
-           if (koenig_p && TREE_CODE (function) == FUNCTION_DECL)
-             /* When KOENIG_P, we don't want to mark_used the callee before
-                augmenting the overload set via ADL, so during this initial
-                substitution we disable mark_used by setting tf_conv (68942).  
*/
-             subcomplain |= tf_conv;
-           function = tsubst_expr (function, args, subcomplain, in_decl);
+           function = tsubst_expr (function, args, complain, in_decl);
if (BASELINK_P (function))
              qualified_p = true;
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 7c7d3e3c432..9e13b690631 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -3321,6 +3321,14 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool 
disallow_virtual,
        if (type_dependent_expression_p (fn)
          || any_type_dependent_arguments_p (*args))
        {
+         if (koenig_p
+             && TREE_CODE (orig_fn) == FUNCTION_DECL
+             && !fndecl_built_in_p (orig_fn))
+           /* For an ADL-enabled call where unqualified lookup found a
+              single non-template function, wrap it in an OVERLOAD so
+              that later substitution doesn't greedily mark the function
+              as used.  */
+           orig_fn = ovl_make (orig_fn, NULL_TREE);
          result = build_min_nt_call_vec (orig_fn, *args);
          SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
          KOENIG_LOOKUP_P (result) = koenig_p;
diff --git a/gcc/testsuite/g++.dg/template/koenig13.C 
b/gcc/testsuite/g++.dg/template/koenig13.C
new file mode 100644
index 00000000000..75c9d95df7e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/koenig13.C
@@ -0,0 +1,16 @@
+// PR c++/119034
+// { dg-do compile { target c++14 } }
+// A version of koenig12.C involving partial instantiation of a generic lambda.
+
+void foo(...) = delete;
+
+template <class T> void lookup(T t) { [&](auto u) { foo(u); }(t); }
+
+namespace N {
+ struct A { };
+ int foo(A);
+}
+
+int main() {
+  lookup(N::A{});
+}

Reply via email to