https://github.com/mugiwaraluffy56 created 
https://github.com/llvm/llvm-project/pull/180325

## Summary

Fixes #180319

Recursive lambdas in templates could cause Clang to crash with a stack overflow 
before hitting the template instantiation depth limit. This happened because 
`LambdaExpressionSubstitution` doesn't count toward the depth limit (by design 
for SFINAE per [temp.deduct]p9).

This PR wraps the `TransformLambdaBody` call in `runWithSufficientStackSpace` 
to handle deeply nested recursive lambdas gracefully:
- If threads are enabled, it runs on a new 8MB stack when stack is nearly 
exhausted
- If threads are disabled, it emits a warning and continues

## Test plan

- Added TEST=4 to `clang/test/SemaTemplate/stack-exhaustion.cpp` with the 
reproduction case from the issue
- The test uses `complexify<200>` which would previously crash but now handles 
gracefully

>From f68179e8cca2912c98d3ab616427771e01077172 Mon Sep 17 00:00:00 2001
From: puneeth_aditya_5656 <[email protected]>
Date: Sat, 7 Feb 2026 12:15:56 +0530
Subject: [PATCH] [Clang] Fix stack overflow with recursive lambdas in
 templates

Wrap the TransformLambdaBody call in runWithSufficientStackSpace to
handle deeply nested recursive lambdas that might exhaust the stack
before hitting the template instantiation depth limit.

LambdaExpressionSubstitution doesn't count toward the template depth
limit (by design for SFINAE per [temp.deduct]p9), so deeply nested
lambda transformations could exhaust the stack and crash the compiler.

This fix ensures that when the stack is nearly exhausted during lambda
transformation, the code either runs on a new stack (if threads are
enabled) or emits a warning and continues gracefully.

Fixes #180319
---
 clang/lib/Sema/TreeTransform.h               | 12 +++++++--
 clang/test/SemaTemplate/stack-exhaustion.cpp | 26 ++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dd061996a0f9e..6ac180671895b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -15963,8 +15963,16 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr 
*E) {
     getSema().pushCodeSynthesisContext(C);
 
     // Instantiate the body of the lambda expression.
-    Body = Invalid ? StmtError()
-                   : getDerived().TransformLambdaBody(E, E->getBody());
+    // Use runWithSufficientStackSpace to handle deeply nested recursive
+    // lambdas that might exhaust the stack before hitting the template
+    // instantiation depth limit.
+    if (Invalid) {
+      Body = StmtError();
+    } else {
+      getSema().runWithSufficientStackSpace(E->getBody()->getBeginLoc(), [&] {
+        Body = getDerived().TransformLambdaBody(E, E->getBody());
+      });
+    }
 
     getSema().popCodeSynthesisContext();
   }
diff --git a/clang/test/SemaTemplate/stack-exhaustion.cpp 
b/clang/test/SemaTemplate/stack-exhaustion.cpp
index c7bfea4132d5e..2883d71f66d60 100644
--- a/clang/test/SemaTemplate/stack-exhaustion.cpp
+++ b/clang/test/SemaTemplate/stack-exhaustion.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -verify %s -DTEST=1
 // RUN: %clang_cc1 -verify %s -DTEST=2
 // RUN: %clang_cc1 -verify %s -DTEST=3
+// RUN: %clang_cc1 -verify %s -DTEST=4 -std=c++20
 // REQUIRES: thread_support
 
 // FIXME: Detection of, or recovery from, stack exhaustion does not work on
@@ -60,6 +61,31 @@ namespace template_parameter_type_recursion {
   void printFunctionalType(ostream &os, mlir::Value &v) { os << v; }
 }
 
+#elif TEST == 4
+
+// Test for recursive lambdas in templates (GitHub issue #180319)
+// This should not crash with a stack overflow.
+namespace recursive_lambda_template {
+  struct foo_tag {};
+  template<class T> struct foo {
+    using tag = foo_tag;
+    T run;
+  };
+  template<class T> concept isFoo = requires(T a) { a.run(); };
+
+  template<int i, class T> auto complexify(T a) requires isFoo<T> {
+    if constexpr (i > 0) {
+      return complexify<i-1>(foo{ [a]{
+        return 1+a.run();
+      }});
+    } else return a;
+  }
+
+  // Use a moderate depth that would previously cause stack exhaustion
+  // but should now be handled gracefully.
+  auto result = complexify<200>(foo{[]{ return 1; }});
+}
+
 #else
 #error unknown test
 #endif

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

Reply via email to