https://github.com/TabbySqui created 
https://github.com/llvm/llvm-project/pull/234915

Mangle the original dependent expression to avoid mangling the function-context 
lambda.

For 'requires' and parameter exprs an original dependent expr is mangled. Thus 
now clang handles enable_if exprs in the same way.

Fixes #233807

>From 1eb63555a647b2b366cd7e313484640cc5497ba7 Mon Sep 17 00:00:00 2001
From: Eugene Velesevich <[email protected]>
Date: Fri, 23 Oct 2026 14:09:11 +0300
Subject: [PATCH] [Clang][ItaniumMangle] Fix infinite recursion mangling a
 lambda in an enable_if condition

Mangle the original dependent expression to avoid mangling
the function-context lambda.

For 'requires' and parameter exprs an original dependent expr is mangled.
Thus now clang handles enable_if exprs in the same way.

Fixes #233807

Co-authored-by: usefahmed07 <[email protected]>
---
 clang/lib/AST/ItaniumMangle.cpp               | 48 +++++++++----------
 .../CodeGenCXX/mangle-lambda-enable-if.cpp    | 10 ++++
 2 files changed, 34 insertions(+), 24 deletions(-)
 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..73c5ed3f60613 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -908,30 +908,6 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) 
{
 }
 
 void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
-  if (FD->hasAttr<EnableIfAttr>()) {
-    FunctionTypeDepthState Saved = FunctionTypeDepth.push();
-    Out << "Ua9enable_ifI";
-    for (AttrVec::const_iterator I = FD->getAttrs().begin(),
-                                 E = FD->getAttrs().end();
-         I != E; ++I) {
-      EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
-      if (!EIA)
-        continue;
-      if (isCompatibleWith(LangOptions::ClangABI::Ver11)) {
-        // Prior to Clang 12, we hardcoded the X/E around enable-if's argument,
-        // even though <template-arg> should not include an X/E around
-        // <expr-primary>.
-        Out << 'X';
-        mangleExpression(EIA->getCond());
-        Out << 'E';
-      } else {
-        mangleTemplateArgExpr(EIA->getCond());
-      }
-    }
-    Out << 'E';
-    FunctionTypeDepth.pop(Saved);
-  }
-
   // When mangling an inheriting constructor, the bare function type used is
   // that of the inherited constructor.
   if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
@@ -964,6 +940,30 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const 
FunctionDecl *FD) {
     FD = PrimaryTemplate->getTemplatedDecl();
   }
 
+  if (FD->hasAttr<EnableIfAttr>()) {
+    FunctionTypeDepthState Saved = FunctionTypeDepth.push();
+    Out << "Ua9enable_ifI";
+    for (AttrVec::const_iterator I = FD->getAttrs().begin(),
+                                 E = FD->getAttrs().end();
+         I != E; ++I) {
+      EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
+      if (!EIA)
+        continue;
+      if (isCompatibleWith(LangOptions::ClangABI::Ver11)) {
+        // Prior to Clang 12, we hardcoded the X/E around enable-if's argument,
+        // even though <template-arg> should not include an X/E around
+        // <expr-primary>.
+        Out << 'X';
+        mangleExpression(EIA->getCond());
+        Out << 'E';
+      } else {
+        mangleTemplateArgExpr(EIA->getCond());
+      }
+    }
+    Out << 'E';
+    FunctionTypeDepth.pop(Saved);
+  }
+
   mangleBareFunctionType(FD->getType()->castAs<FunctionProtoType>(),
                          MangleReturnType, FD);
 }
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..7fc3c31dc17d6
--- /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_ifIXclL3$_0EEEEiv"()
+int y = get();

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

Reply via email to