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
