https://github.com/GeneralK1ng updated 
https://github.com/llvm/llvm-project/pull/176896

>From 962a9ef62e3be3bca293d5a176a90c47b97cef21 Mon Sep 17 00:00:00 2001
From: General_K1ng <[email protected]>
Date: Tue, 20 Jan 2026 19:03:18 +0800
Subject: [PATCH 1/3] [Clang] Avoid crashing on substitution failure in
 expression requirements

---
 clang/lib/AST/ExprConcepts.cpp                |  9 +++++++--
 .../concepts-crash-expr-requirement.cpp       | 19 +++++++++++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp

diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp
index 36f910da49bfb..b2e4d6b00a647 100644
--- a/clang/lib/AST/ExprConcepts.cpp
+++ b/clang/lib/AST/ExprConcepts.cpp
@@ -101,8 +101,13 @@ 
concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {
 // Search through the requirements, and see if any have a RecoveryExpr in it,
 // which means this RequiresExpr ALSO needs to be invalid.
 static bool RequirementContainsError(concepts::Requirement *R) {
-  if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R))
-    return ExprReq->getExpr() && ExprReq->getExpr()->containsErrors();
+  if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) {
+    if (ExprReq->isExprSubstitutionFailure())
+      return true;
+    if (auto *E = ExprReq->getExpr())
+      return E->containsErrors();
+    return false;
+  }
 
   if (auto *NestedReq = dyn_cast<concepts::NestedRequirement>(R))
     return !NestedReq->hasInvalidConstraint() &&
diff --git a/clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp 
b/clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp
new file mode 100644
index 0000000000000..9e6474371a245
--- /dev/null
+++ b/clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp
@@ -0,0 +1,19 @@
+// RUN: not %clang_cc1 -std=c++23 -fsyntax-only %s 2>&1 | FileCheck %s
+// Regression test: don't crash when an expression requirement becomes a
+// substitution failure during template instantiation (see #176402).
+
+void f() {
+    auto recursiveLambda = [](auto self, int depth) -> void {
+        struct MyClass;
+        auto testConcept = []<typename T> {
+            return requires(T) { &MyClass::operator0 }
+        };
+    };
+    recursiveLambda(recursiveLambda, 5);
+}
+
+// CHECK: error:
+// CHECK: expected ';' at end of requirement
+// CHECK-NOT: Assertion failed
+// CHECK-NOT: Stack dump:
+

>From 6eb6b066cbc481a4f3d58d406fa487883d79e693 Mon Sep 17 00:00:00 2001
From: General_K1ng <[email protected]>
Date: Tue, 20 Jan 2026 22:32:54 +0800
Subject: [PATCH 2/3] refactor(concepts): consolidate concept requirement tests

---
 .../concepts-crash-expr-requirement.cpp       | 19 -------------------
 clang/test/SemaTemplate/concepts.cpp          | 13 +++++++++++++
 2 files changed, 13 insertions(+), 19 deletions(-)
 delete mode 100644 clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp

diff --git a/clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp 
b/clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp
deleted file mode 100644
index 9e6474371a245..0000000000000
--- a/clang/test/SemaTemplate/concepts-crash-expr-requirement.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: not %clang_cc1 -std=c++23 -fsyntax-only %s 2>&1 | FileCheck %s
-// Regression test: don't crash when an expression requirement becomes a
-// substitution failure during template instantiation (see #176402).
-
-void f() {
-    auto recursiveLambda = [](auto self, int depth) -> void {
-        struct MyClass;
-        auto testConcept = []<typename T> {
-            return requires(T) { &MyClass::operator0 }
-        };
-    };
-    recursiveLambda(recursiveLambda, 5);
-}
-
-// CHECK: error:
-// CHECK: expected ';' at end of requirement
-// CHECK-NOT: Assertion failed
-// CHECK-NOT: Stack dump:
-
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index d93391baf9926..2701c16f56fc0 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1713,3 +1713,16 @@ template<C<void, bool> T> int f();
 void main() { f<int>(); }
 
 }
+
+namespace GH176402 {
+  void f() {
+    auto recursiveLambda = [](auto self, int depth) -> void {
+      struct MyClass;
+      auto testConcept = []<typename T> {
+        return requires(T) { &MyClass::operator0 }
+        // expected-error {{expected ';' at end of requirement}}
+      };
+    };
+    recursiveLambda(recursiveLambda, 5);
+  }
+}

>From 2cc0b9b9a6de60aea7b2944315165b76e6966251 Mon Sep 17 00:00:00 2001
From: General_K1ng <[email protected]>
Date: Tue, 20 Jan 2026 22:40:40 +0800
Subject: [PATCH 3/3] doc: add release note

---
 clang/docs/ReleaseNotes.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bde3bb1e81210..611e3fba2bc2b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -137,6 +137,7 @@ Bug Fixes to Attribute Support
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed a crash when instantiating ``requires`` expressions involving 
substitution failures in C++ concepts. (#GH176402)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

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

Reply via email to