[clang] [CLANG] Fixes the crash on the use of nested requirements in require expressions (PR #169876)
Ebin Jose via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 3 20:35:53 PST 2025
https://github.com/ebinjose02 updated https://github.com/llvm/llvm-project/pull/169876
>From af9b88da83a7f2954a3a8ddc5f4796f2017ceaec Mon Sep 17 00:00:00 2001
From: ebinjose02 <ebin371 at gmail.com>
Date: Fri, 28 Nov 2025 06:46:40 +0000
Subject: [PATCH 1/3] Fixes #165386 Nested requirements in requires-expressions
must be constant expressions. Previously, using an invented parameter in a
nested requirement caused a crash. Now emit a clear diagnostic and recover.
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
clang/lib/Sema/SemaExprCXX.cpp | 8 ++++++++
clang/test/SemaCXX/requires-nested-non-constant.cpp | 11 +++++++++++
3 files changed, 21 insertions(+)
create mode 100644 clang/test/SemaCXX/requires-nested-non-constant.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4a145fd71eedd..8083fde95f2ab 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3190,6 +3190,8 @@ def note_ambiguous_atomic_constraints_similar_expression : Note<
def err_unsupported_placeholder_constraint : Error<
"constrained placeholder types other than simple 'auto' on non-type template "
"parameters not supported yet">;
+def err_nested_requirement_not_constant : Error<
+ "nested requirement is not a constant expression">;
def err_template_different_requires_clause : Error<
"requires clause differs in template redeclaration">;
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index d6f70e728be29..490ce09e75208 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7922,6 +7922,14 @@ concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) {
concepts::NestedRequirement *
Sema::BuildNestedRequirement(Expr *Constraint) {
+ if (!Constraint->isValueDependent() &&
+ !Constraint->isInstantiationDependent()) {
+ Expr::EvalResult Result;
+ if (!Constraint->EvaluateAsConstantExpr(Result, Context)) {
+ Diag(Constraint->getExprLoc(), diag::err_nested_requirement_not_constant);
+ return nullptr;
+ }
+ }
ConstraintSatisfaction Satisfaction;
if (!Constraint->isInstantiationDependent() &&
CheckConstraintSatisfaction(nullptr, AssociatedConstraint(Constraint),
diff --git a/clang/test/SemaCXX/requires-nested-non-constant.cpp b/clang/test/SemaCXX/requires-nested-non-constant.cpp
new file mode 100644
index 0000000000000..acb516392e616
--- /dev/null
+++ b/clang/test/SemaCXX/requires-nested-non-constant.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
+
+template <class C> class A {
+ void f() {
+ auto result = []() constexpr {
+ return requires (int x) {
+ requires (x > 0) && (x < 10); // expected-error {{nested requirement is not a constant expression}}
+ };
+ }();
+ }
+};
>From 2de5ef4d02f9d0aed61cebacb14517381aeeb9e7 Mon Sep 17 00:00:00 2001
From: ebinjose02 <ebin371 at gmail.com>
Date: Tue, 2 Dec 2025 09:22:10 +0000
Subject: [PATCH 2/3] Modified implementation to use instantationscope
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 --
clang/lib/Sema/SemaExprCXX.cpp | 10 ++--------
clang/test/SemaCXX/requires-nested-non-constant.cpp | 6 ++++--
3 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8083fde95f2ab..4a145fd71eedd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3190,8 +3190,6 @@ def note_ambiguous_atomic_constraints_similar_expression : Note<
def err_unsupported_placeholder_constraint : Error<
"constrained placeholder types other than simple 'auto' on non-type template "
"parameters not supported yet">;
-def err_nested_requirement_not_constant : Error<
- "nested requirement is not a constant expression">;
def err_template_different_requires_clause : Error<
"requires clause differs in template redeclaration">;
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 490ce09e75208..f915caffa3487 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7922,16 +7922,10 @@ concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) {
concepts::NestedRequirement *
Sema::BuildNestedRequirement(Expr *Constraint) {
- if (!Constraint->isValueDependent() &&
- !Constraint->isInstantiationDependent()) {
- Expr::EvalResult Result;
- if (!Constraint->EvaluateAsConstantExpr(Result, Context)) {
- Diag(Constraint->getExprLoc(), diag::err_nested_requirement_not_constant);
- return nullptr;
- }
- }
ConstraintSatisfaction Satisfaction;
+ LocalInstantiationScope Scope(*this);
if (!Constraint->isInstantiationDependent() &&
+ !Constraint->isValueDependent() &&
CheckConstraintSatisfaction(nullptr, AssociatedConstraint(Constraint),
/*TemplateArgs=*/{},
Constraint->getSourceRange(), Satisfaction))
diff --git a/clang/test/SemaCXX/requires-nested-non-constant.cpp b/clang/test/SemaCXX/requires-nested-non-constant.cpp
index acb516392e616..b5b8bdbf5a9dc 100644
--- a/clang/test/SemaCXX/requires-nested-non-constant.cpp
+++ b/clang/test/SemaCXX/requires-nested-non-constant.cpp
@@ -3,8 +3,10 @@
template <class C> class A {
void f() {
auto result = []() constexpr {
- return requires (int x) {
- requires (x > 0) && (x < 10); // expected-error {{nested requirement is not a constant expression}}
+ return requires (int x) { // expected-note {{declared here}}
+ requires (x > 0) && (x < 10); // expected-error {{substitution into constraint expression resulted in a non-constant expression}} \
+ // expected-note {{while checking the satisfaction of nested requirement requested here}} \
+ // expected-note {{function parameter 'x' with unknown value cannot be used in a constant expression}}
};
}();
}
>From 113a1afe2d9fb3d1652dbd1bc49e71d678ea94b4 Mon Sep 17 00:00:00 2001
From: ebinjose02 <ebin371 at gmail.com>
Date: Wed, 3 Dec 2025 04:50:32 +0000
Subject: [PATCH 3/3] Added documentation in ReleaseNotes.rst
---
clang/docs/ReleaseNotes.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c6a79ed71ca2f..4404ddc9f7e45 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -724,6 +724,8 @@ Crash and bug fixes
``[[assume(expr)]]`` attribute was enclosed in parentheses. (#GH151529)
- Fixed a crash when parsing ``#embed`` parameters with unmatched closing brackets. (#GH152829)
- Fixed a crash when compiling ``__real__`` or ``__imag__`` unary operator on scalar value with type promotion. (#GH160583)
+- Fixed a crash when evaluating nested requirements in requires-expressions that
+ reference invented parameters. (#GH166325)
Improvements
^^^^^^^^^^^^
More information about the cfe-commits
mailing list