https://github.com/jiixyj updated https://github.com/llvm/llvm-project/pull/179035
From 72d814fb6d05ae529538d5b673277e6c065bbbb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kokem=C3=BCller?= <[email protected]> Date: Sat, 31 Jan 2026 14:26:59 +0100 Subject: [PATCH 1/4] Don't use VarDecl of local variables as ManglingContextDecl for lambdas --- clang/lib/Sema/SemaLambda.cpp | 8 ++++++++ clang/test/Modules/pr178893.cppm | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 clang/test/Modules/pr178893.cppm diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e74fe02bd0cf5..24426259bf01c 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -294,6 +294,14 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { bool IsInNonspecializedTemplate = inTemplateInstantiation() || CurContext->isDependentContext(); + // If we must allocate mangling numbers but the `ManglingContextDecl` + // is a local variable, use the `DeclContext` containing the lambda expression + // instead. + if (ManglingContextDecl) + if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl); + Var && Var->isLocalVarDecl()) + ManglingContextDecl = const_cast<Decl *>(cast<Decl>(DC)); + // Default arguments of member function parameters that appear in a class // definition, as well as the initializers of data members, receive special // treatment. Identify them. diff --git a/clang/test/Modules/pr178893.cppm b/clang/test/Modules/pr178893.cppm new file mode 100644 index 0000000000000..6d2a599588667 --- /dev/null +++ b/clang/test/Modules/pr178893.cppm @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++20 -triple x86_64-apple-macosx10.7.0 -fmodules -xc++ -emit-llvm -o - %s -w | FileCheck %s + +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZZN8PR178893W3mod6format5parseEPiENKUlvE_clEv +// CHECK-LABEL: define linkonce_odr noundef i32 @_ZZN8PR178893W3mod6format5parseEPiENKUlvE0_clEv + +export module mod; + +namespace PR178893 { + struct format { + static inline int parse(int* i) + { + int number; + number = [&]() -> int { return i[0]; }(); + + volatile bool b = true; + if (b) { + auto identifier = [&]() -> int { return i[1]; }(); + return identifier; + } + + return number; + } + }; + + int test_format() { + int n[2] = {1, 0}; + return format::parse(n); + } +} From d5dbb1738f1d2c90850d27ba5e3e7245e6f325ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kokem=C3=BCller?= <[email protected]> Date: Sun, 1 Feb 2026 10:45:25 +0100 Subject: [PATCH 2/4] Use `dyn_cast_or_null` instead of null check plus `dyn_cast` Co-authored-by: Corentin Jabot <[email protected]> --- clang/lib/Sema/SemaLambda.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 24426259bf01c..cdefd60508164 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -297,8 +297,7 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { // If we must allocate mangling numbers but the `ManglingContextDecl` // is a local variable, use the `DeclContext` containing the lambda expression // instead. - if (ManglingContextDecl) - if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl); + if (VarDecl *Var = dyn_cast_or_null<VarDecl>(ManglingContextDecl); Var && Var->isLocalVarDecl()) ManglingContextDecl = const_cast<Decl *>(cast<Decl>(DC)); From 42bb683d0d44e008408f542b01e192a4d192e273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kokem=C3=BCller?= <[email protected]> Date: Sun, 1 Feb 2026 10:56:51 +0100 Subject: [PATCH 3/4] Autoformat --- clang/lib/Sema/SemaLambda.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index cdefd60508164..1066333722bd8 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -298,8 +298,8 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { // is a local variable, use the `DeclContext` containing the lambda expression // instead. if (VarDecl *Var = dyn_cast_or_null<VarDecl>(ManglingContextDecl); - Var && Var->isLocalVarDecl()) - ManglingContextDecl = const_cast<Decl *>(cast<Decl>(DC)); + Var && Var->isLocalVarDecl()) + ManglingContextDecl = const_cast<Decl *>(cast<Decl>(DC)); // Default arguments of member function parameters that appear in a class // definition, as well as the initializers of data members, receive special From 4be67cb8356bf53bfe074663dc47792cb66fecf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kokem=C3=BCller?= <[email protected]> Date: Mon, 2 Feb 2026 13:10:49 +0100 Subject: [PATCH 4/4] Refactor so that fallback only applies to module case --- clang/lib/Sema/SemaLambda.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 1066333722bd8..f7fd1d1831500 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -294,13 +294,6 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { bool IsInNonspecializedTemplate = inTemplateInstantiation() || CurContext->isDependentContext(); - // If we must allocate mangling numbers but the `ManglingContextDecl` - // is a local variable, use the `DeclContext` containing the lambda expression - // instead. - if (VarDecl *Var = dyn_cast_or_null<VarDecl>(ManglingContextDecl); - Var && Var->isLocalVarDecl()) - ManglingContextDecl = const_cast<Decl *>(cast<Decl>(DC)); - // Default arguments of member function parameters that appear in a class // definition, as well as the initializers of data members, receive special // treatment. Identify them. @@ -311,12 +304,24 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { // Yeah, I think the only cases left where lambdas don't need a // mangling are when they have (effectively) internal linkage or appear // in a non-inline function in a non-module translation unit. - if (auto *ND = dyn_cast<NamedDecl>(ManglingContextDecl ? ManglingContextDecl - : cast<Decl>(DC)); + + Decl *ManglingContextDeclForModule = [&]() { + if (!ManglingContextDecl || [&]() { + // If we must allocate mangling numbers but the + // `ManglingContextDecl` is a local variable, use the `DeclContext` + // containing the lambda expression instead. + VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl); + return Var && Var->isLocalVarDecl(); + }()) + return const_cast<Decl *>(cast<Decl>(DC)); + + return ManglingContextDecl; + }(); + + if (auto *ND = dyn_cast<NamedDecl>(ManglingContextDeclForModule); ND && (ND->isInNamedModule() || ND->isFromGlobalModule()) && ND->isExternallyVisible()) { - if (!ManglingContextDecl) - ManglingContextDecl = const_cast<Decl *>(cast<Decl>(DC)); + ManglingContextDecl = ND; return NonInlineInModulePurview; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
