Skip to content

[clang] Backport: stop error recovery in SFINAE for narrowing in converted constant expressions - #183819

Merged
dyung merged 1 commit into
release/22.xfrom
users/mizvekov/GH167709
Feb 28, 2026
Merged

dyung merged 1 commit into
release/22.xfrom
users/mizvekov/GH167709

Conversation

@mizvekov

@mizvekov mizvekov commented Feb 27, 2026

Copy link
Copy Markdown
Contributor

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.

Backport from #183614

Fixes #167709

@mizvekov mizvekov self-assigned this Feb 27, 2026
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Feb 27, 2026
@llvmbot

llvmbot commented Feb 27, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/183819.diff

2 Files Affected:

  • (modified) clang/lib/Sema/SemaOverload.cpp (+8)
  • (modified) clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp (+10-1)
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@+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

@zwuis zwuis added this to the LLVM 22.x Release milestone Feb 28, 2026
@github-project-automation github-project-automation Bot moved this to Needs Triage in LLVM Release Status Feb 28, 2026
@github-project-automation github-project-automation Bot moved this from Needs Triage to Needs Merge in LLVM Release Status Feb 28, 2026
…erted 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
@dyung
dyung force-pushed the users/mizvekov/GH167709 branch from 86996aa to 698202d Compare February 28, 2026 09:22
@dyung
dyung merged commit 698202d into release/22.x Feb 28, 2026
2 of 3 checks passed
@dyung
dyung deleted the users/mizvekov/GH167709 branch February 28, 2026 09:22
@github-project-automation github-project-automation Bot moved this from Needs Merge to Done in LLVM Release Status Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

Development

Successfully merging this pull request may close these issues.

5 participants