https://github.com/ojhunt updated 
https://github.com/llvm/llvm-project/pull/211705

>From f8357566dde882ef967c7cf5383ecd2785e08859 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <[email protected]>
Date: Thu, 23 Jul 2026 18:14:07 -0700
Subject: [PATCH] [clang][sema] Call expressions are constructed for undeduced
 deleted functions (#208488)

The deleted function path of overload resolution always constructed a CallExpr 
node
for the called function even if the function could not be deduced.
This case is handled in other paths by DiagnoseUseOfDecl which does perform that
test. The delete path cannot use that path though, as DiagnoseUseOfDecl rejects
deleted functions, and the entire point of this code is to permit the continued
evaluation of code even if the resolved function was deleted.

To fix this we now manually check for a complete type before continuing to 
construct
a potentially bogus CallExpr.
---
 clang/lib/Sema/SemaOverload.cpp               |  4 ++
 .../SemaCXX/deduced-return-type-cxx14.cpp     |  3 ++
 .../deleted-function-deduction-failure.cpp    | 49 +++++++++++++++++++
 3 files changed, 56 insertions(+)
 create mode 100644 clang/test/SemaCXX/deleted-function-deduction-failure.cpp

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d66dea0d918fa..d79d4b1721b27 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -15027,6 +15027,10 @@ static ExprResult FinishOverloadedCallExpr(Sema 
&SemaRef, Scope *S, Expr *Fn,
                                          Fn->getSourceRange(), ULE->getName(),
                                          *CandidateSet, FDecl, Args);
 
+    if (completeFunctionType(SemaRef, FDecl, Fn->getBeginLoc(),
+                             /*Complain=*/true))
+      return ExprError();
+
     // We emitted an error for the unavailable/deleted function call but keep
     // the call in the AST.
     ExprResult Res =
diff --git a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp 
b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
index 10ea9e82f5327..1bcce2fe958bc 100644
--- a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -359,7 +359,10 @@ namespace NoReturn {
   auto *g() {} // expected-error {{cannot deduce return type 'auto *' for 
function with no return statements}}
 
   auto h() = delete; // expected-note {{explicitly deleted}}
+  // expected-note@-1 {{'h' declared here}}
+
   auto x = h(); // expected-error {{call to deleted}}
+  // expected-error@-1 {{function 'h' with deduced return type cannot be used 
before it is defined}}
 }
 
 namespace UseBeforeComplete {
diff --git a/clang/test/SemaCXX/deleted-function-deduction-failure.cpp 
b/clang/test/SemaCXX/deleted-function-deduction-failure.cpp
new file mode 100644
index 0000000000000..7a50a81926b70
--- /dev/null
+++ b/clang/test/SemaCXX/deleted-function-deduction-failure.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+
+
+namespace UndeducedDeletedFunction {
+auto deleted_auto() = delete; // #deleted_auto_decl
+// expected-note@#deleted_auto_decl {{candidate function has been explicitly 
deleted}}
+// expected-note@#deleted_auto_decl {{'deleted_auto' declared here}}
+
+auto auto_test() {
+  auto x = deleted_auto(); // #auto_use
+  // expected-error@#auto_use {{call to deleted function 'deleted_auto'}}
+  // expected-note@#deleted_auto_decl {{candidate function has been explicitly 
deleted}}
+  // expected-error@#auto_use {{function 'deleted_auto' with deduced return 
type cannot be used before it is defined}}
+  // expected-note@#deleted_auto_decl {{'deleted_auto' declared here}}
+  return x;
+}
+
+auto decltype_auto_test() {
+  decltype(auto) x = deleted_auto(); // #decl_type_use
+  // expected-error@#decl_type_use {{call to deleted function 'deleted_auto'}}
+  // expected-note@#deleted_auto_decl {{candidate function has been explicitly 
deleted}}
+  // expected-error@#decl_type_use {{function 'deleted_auto' with deduced 
return type cannot be used before it is defined}}
+  // expected-note@#deleted_auto_decl {{'deleted_auto' declared here}}
+  return x;
+}
+
+auto decltype_auto_type_test() {
+  __auto_type x = deleted_auto(); // #__auto_type_use
+  // expected-error@#__auto_type_use {{call to deleted function 
'deleted_auto'}}
+  // expected-error@#__auto_type_use {{function 'deleted_auto' with deduced 
return type cannot be used before it is defined}}
+  return x;
+}
+}
+
+namespace DeletedWithUnresolvedExceptionSpec {
+struct X {};
+
+template <typename T> void failed_exception_spec(T) noexcept(T::value) = 
delete; // #failed_exception_spec_declared
+// expected-error@#failed_exception_spec_declared {{no member named 'value' in 
'DeletedWithUnresolvedExceptionSpec::X'}}
+// expected-note@#failed_exception_used {{in instantiation of exception 
specification for 
'failed_exception_spec<DeletedWithUnresolvedExceptionSpec::X>' requested here}}
+
+void g() {
+  failed_exception_spec(X{}); // #failed_exception_used
+  // expected-error@#failed_exception_used {{call to deleted function 
'failed_exception_spec'}}
+  // expected-note@#failed_exception_spec_declared {{candidate function [with 
T = DeletedWithUnresolvedExceptionSpec::X] has been explicitly deleted}}
+}
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to