Author: General_K1ng
Date: 2026-01-20T16:35:49Z
New Revision: b515e1182560f91a7c7a459186dea5299f62534a

URL: 
https://github.com/llvm/llvm-project/commit/b515e1182560f91a7c7a459186dea5299f62534a
DIFF: 
https://github.com/llvm/llvm-project/commit/b515e1182560f91a7c7a459186dea5299f62534a.diff

LOG: [Clang] Avoid crash when expression requirements are substitution failures 
(#176896)

Clang could assert in `clang::concepts::ExprRequirement::getExpr()` when
an expression requirement becomes a substitution failure during template
instantiation.

Substitution-failure `ExprRequirements` intentionally do not have an
associated expression. Calling `getExpr()` in this case violates the API
contract and triggers an assertion.

This occurred while checking requirements in `RequirementContainsError`
during `RequiresExpr` construction.

Guard `RequirementContainsError` against substitution-failure
`ExprRequirements` and avoid calling `getExpr()` in that case.

Fixes #176402
Fixes #115513
Fixes #130620

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/ExprConcepts.cpp
    clang/test/SemaTemplate/concepts.cpp

Removed: 
    


################################################################################
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
 ^^^^^^^^^^^^^^^^^^^^^^^^^

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.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index d93391baf9926..cbb7e6dfb96d7 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1713,3 +1713,15 @@ 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);
+  }
+}


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

Reply via email to