https://github.com/usefahmed07 updated 
https://github.com/llvm/llvm-project/pull/234686

>From f9abf0da2c70ec5401d91c7b0437e7bcd59a2d50 Mon Sep 17 00:00:00 2001
From: usefahmed07 <[email protected]>
Date: Thu, 22 Oct 2026 19:39:08 +0300
Subject: [PATCH] [Clang][ItaniumMangle] Fix infinite recursion mangling lambda
 in enable_if (#233807)

---
 clang/lib/AST/ItaniumMangle.cpp               | 30 +++++++++++++++++++
 .../CodeGenCXX/mangle-lambda-enable-if.cpp    | 10 +++++++
 2 files changed, 40 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/mangle-lambda-enable-if.cpp

diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 02f27cec53f69..ae4166918932e 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -649,6 +649,18 @@ static const CXXRecordDecl *getLambdaForInitCapture(const 
VarDecl *VD) {
   return Lambda;
 }
 
+/// Returns true if \p S contains the lambda expression defining \p Lambda.
+static bool containsLambdaExpr(const Stmt *S, const CXXRecordDecl *Lambda) {
+  if (!S)
+    return false;
+  if (const auto *LE = dyn_cast<LambdaExpr>(S))
+    if (LE->getLambdaClass() == Lambda)
+      return true;
+  return llvm::any_of(S->children(), [&](const Stmt *Child) {
+    return containsLambdaExpr(Child, Lambda);
+  });
+}
+
 /// Retrieve the declaration context that should be used when mangling the 
given
 /// declaration.
 const DeclContext *
@@ -664,6 +676,24 @@ ItaniumMangleContextImpl::getEffectiveDeclContext(const 
Decl *D) {
       if (ParmVarDecl *ContextParam =
               dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
         return ContextParam->getDeclContext();
+
+    // A lambda in the condition of an enable_if/diagnose_if attribute is
+    // instantiated with the function as its DeclContext, but the ABI treats it
+    // like the dependent pattern: it lives in the function's parent context.
+    // Mangling it relative to the function would recurse forever, since the
+    // function's encoding includes the attribute condition.
+    if (RD->isLambda() && !RD->getLambdaContextDecl())
+      if (const auto *FD = dyn_cast<FunctionDecl>(RD->getDeclContext())) {
+        for (const Attr *A : FD->attrs()) {
+          const Expr *Cond = nullptr;
+          if (const auto *EIA = dyn_cast<EnableIfAttr>(A))
+            Cond = EIA->getCond();
+          else if (const auto *DIA = dyn_cast<DiagnoseIfAttr>(A))
+            Cond = DIA->getCond();
+          if (containsLambdaExpr(Cond, RD))
+            return FD->getDeclContext();
+        }
+      }
   }
 
   // Perform the same check for block literals.
diff --git a/clang/test/CodeGenCXX/mangle-lambda-enable-if.cpp 
b/clang/test/CodeGenCXX/mangle-lambda-enable-if.cpp
new file mode 100644
index 0000000000000..fd92cd1aa65d3
--- /dev/null
+++ b/clang/test/CodeGenCXX/mangle-lambda-enable-if.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple x86_64-linux-gnu | 
FileCheck %s
+
+// Mangling a lambda in an enable_if condition must not recurse infinitely.
+// https://github.com/llvm/llvm-project/issues/233807
+template <int = 0>
+int get() __attribute__((enable_if([]() { return true; }(), ""))) { return 0; }
+
+// CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+// CHECK: call {{.*}} @_Z3getILi0EEUa9enable_ifIXclLUlvE_EEEiv()
+int y = get();

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

Reply via email to