https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/183614

>From 25c946cadc87fd74cfeb950c12202a3a6d75077a Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <[email protected]>
Date: Thu, 26 Feb 2026 16:33:36 -0300
Subject: [PATCH] [clang] stop error recovery in SFINAE for narrowing in
 converted constant expressions

A narrowing conversion in a converted constant expression should produce an
invalid expression so that [temp.deduct.general]p7 is satisfied, by stopping
substitution at this point.

Fixes #167709
---
 clang/lib/Sema/SemaOverload.cpp                    |  8 ++++++++
 clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp | 11 ++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 41b0b64409fd5..1736bec3f1538 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6470,6 +6470,12 @@ static ExprResult BuildConvertedConstantExpression(Sema 
&S, Expr *From,
     S.Diag(From->getBeginLoc(), diag::ext_cce_narrowing)
         << CCE << /*Constant*/ 1
         << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << T;
+    // If this is an SFINAE Context, treat the result as invalid so it stops
+    // substitution at this point, respecting C++26 [temp.deduct.general]p7.
+    // FIXME: Should do this whenever the above diagnostic is an error, but
+    // without further changes this would degrade some other diagnostics.
+    if (S.isSFINAEContext())
+      return ExprError();
     break;
 
   case NK_Dependent_Narrowing:
@@ -6485,6 +6491,8 @@ static ExprResult BuildConvertedConstantExpression(Sema 
&S, Expr *From,
     // constant expression.
     S.Diag(From->getBeginLoc(), diag::ext_cce_narrowing)
         << CCE << /*Constant*/ 0 << From->getType() << T;
+    if (S.isSFINAEContext())
+      return ExprError();
     break;
   }
   if (!ReturnPreNarrowingValue)
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp 
b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index 45bdb4c623dfe..0b785700ee238 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -43,7 +43,7 @@ void TempFunc() {}
 
 void Useage() {
   //expected-error@+2 {{no matching function}}
-  //expected-note@-4 {{candidate template ignored: substitution failure [with 
a = 1, b = 4294967295, c = 1]: non-type template argument evaluates to -1, 
which cannot be narrowed to type 'unsigned int'}}
+  //expected-note@-4 {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'b'}}
   TempFunc<1, -1, 1>();
 }
 }
@@ -114,3 +114,12 @@ void lookup() {
   Kolumn<&container::a>().ls();   // expected-error {{<&container::a}}
   Kolumn<nullptr>().ls();         // expected-error {{<nullptr}}
 }
+
+namespace GH167709 {
+  template <unsigned I> struct A {
+    static_assert(false, "shouldn't instantiate this");
+  };
+  template <int> void f() {}
+  template <int I> typename A<I>::type f() = delete;
+  template void f<-1>();
+} // namespace GH167709

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

Reply via email to