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
