[clang] [Clang][Sema] Fix an assertion crash when instantiating a nested requirement (PR #213660)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 3 05:52:38 PDT 2026
https://github.com/babadany2999 created https://github.com/llvm/llvm-project/pull/213660
### Summary
Fixed an assertion crash when instantiating a nested requirement with an invalid constraint.
Fixes #213575
### Details
In `clang/lib/Sema/SemaTemplateInstantiate.cpp`, inside the method `TransformNestedRequirement`, the check for `concepts::NestedRequirement*` (more explicitly, `if (Req->hasInvalidConstraint())`) was being executed too late, as `Req->getConstraintExpr` has already been executed, which contained the assertion.
### Test Plan
- Added regression test to `clang/test/SemaTemplate/gh213575.cpp`
- Verified test fails without the patch and passes with the patch across `clang/test/SemaTemplate`, `clang/test/SemaCXX` and `clang/test/Sema`
cc @cor3ntin - I've noticed your recent refactoring in `TransformNestedRequirement` (`e9972de`) introduced this ordering issue. Whenever you have a moment, I'd appreciate your review on this fix!
>From 173eb3b1d021e9b5fbf685ab3a3e8d390ceba22a Mon Sep 17 00:00:00 2001
From: Baba Dan Constantin <babadany2999 at gmail.com>
Date: Mon, 3 Aug 2026 15:36:58 +0300
Subject: [PATCH] [Clang][Sema] Fix an assertion crash when instantiating a
nested requirement with an invalid constraint. (#GH213575)
---
clang/docs/ReleaseNotes.md | 1 +
clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 +++++++-------
clang/test/SemaTemplate/gh213575.cpp | 15 +++++++++++++++
3 files changed, 23 insertions(+), 7 deletions(-)
create mode 100644 clang/test/SemaTemplate/gh213575.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a38b99ff8e075..fac0526ae42da 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -365,6 +365,7 @@ features cannot lower the translation-unit ABI level;
- Fixed a bug where `__func__`, `__PRETTY_FUNCTION__` and `__FUNCTION__` were not resolving to the proper function when inside a lambda return type (#GH211811)
- Fixed USR generation for declarations whose signature mentions a class-type
non-type template parameter. (#GH212351)
+- Fixed an assertion crash when instantiating a nested requirement with an invalid constraint. (#GH213575)
#### Bug Fixes to Compiler Builtins
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 2cf2a4f85f830..1ebb92e5d06d6 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2832,6 +2832,13 @@ TemplateInstantiator::TransformNestedRequirement(
ASTContext &C = SemaRef.Context;
+ if (Req->hasInvalidConstraint()) {
+ if (AlwaysRebuild())
+ return RebuildNestedRequirement(Req->getInvalidConstraintEntity(),
+ Req->getConstraintSatisfaction());
+ return Req;
+ }
+
Expr *Constraint = Req->getConstraintExpr();
ConstraintSatisfaction Satisfaction;
@@ -2845,13 +2852,6 @@ TemplateInstantiator::TransformNestedRequirement(
SemaRef.Context, C.backupStr(Entity), std::move(Satisfaction));
};
- if (Req->hasInvalidConstraint()) {
- if (AlwaysRebuild())
- return RebuildNestedRequirement(Req->getInvalidConstraintEntity(),
- Req->getConstraintSatisfaction());
- return Req;
- }
-
if (!getEvaluateConstraints()) {
ExprResult TransConstraint = TransformExpr(Req->getConstraintExpr());
if (TransConstraint.isInvalid() || !TransConstraint.get())
diff --git a/clang/test/SemaTemplate/gh213575.cpp b/clang/test/SemaTemplate/gh213575.cpp
new file mode 100644
index 0000000000000..963d518f9fe65
--- /dev/null
+++ b/clang/test/SemaTemplate/gh213575.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+
+struct S {};
+template <typename T> bar C; // expected-error {{unknown type name 'bar'}}
+
+template <typename U> auto foo() {
+ return []<typename T>(
+ T, bool b = requires { C<T>; }) {
+ static_assert(requires { requires C<U>; }); // expected-error {{static assertion failed due to requirement 'requires { requires <<error-expression>>; }'}}
+ return 0;
+ };
+}
+
+auto baz = foo<int>();
+int qux = baz(S{}); // expected-note {{in instantiation of function template specialization 'foo()::(lambda)::operator()<S>' requested here}}
\ No newline at end of file
More information about the cfe-commits
mailing list