[llvm-branch-commits] [clang] [clang] Backport: stop error recovery in SFINAE for narrowing in converted constant expressions (PR #183819)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Feb 28 01:22:27 PST 2026
https://github.com/dyung updated https://github.com/llvm/llvm-project/pull/183819
>From 698202df0127aaee8b37bc2834e9b47d09e648f7 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Thu, 26 Feb 2026 16:33:36 -0300
Subject: [PATCH] [clang] Backport: 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 7115b8b7d446a..0b6296e9b2efa 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 at +2 {{no matching function}}
- //expected-note at -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 at -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
More information about the llvm-branch-commits
mailing list