https://github.com/yuxuanchen1997 updated 
https://github.com/llvm/llvm-project/pull/196597

>From e39df0f164091095fea19c49dd48a1912fb6acf7 Mon Sep 17 00:00:00 2001
From: Yuxuan Chen <[email protected]>
Date: Thu, 7 May 2026 20:24:49 -0700
Subject: [PATCH] [Clang] Rebind the closure temporary when rebuilding default
 member initializers

Fixes https://github.com/llvm/llvm-project/issues/196469

Since the CWG1815 implementation, InitListChecker rebuilds a default
member initializer at its point of use in aggregate initialization. The
rebuild uses the EnsureImmediateInvocationInDefaultArgs tree transform,
where TransformCXXBindTemporaryExpr strips CXXBindTemporaryExpr nodes,
relying on the subexpression's rebuild to re-create the temporary
binding: every Rebuild path funnels through Sema::MaybeBindToTemporary,
which also re-registers the cleanup in the current evaluation context.

However, the transform overrides TransformLambdaExpr to return the
closure unchanged (the body is not a subexpression), skipping the
MaybeBindToTemporary call that BuildLambdaExpr ends with. The rebuilt
initializer then lacks both the CXXBindTemporaryExpr around the closure
and the ExprWithCleanups marker, so CodeGen never emits the closure's
destructor and init-captured members leak.

Restore the side effect in the override: re-bind the closure to a
temporary, exactly as building the lambda would have. This is a no-op
for trivially destructible closures.

Co-Authored-By: Claude Fable 5 <[email protected]>
---
 clang/lib/Sema/SemaExpr.cpp                   | 12 ++++++++--
 ...469-default-member-init-lambda-cleanup.cpp | 24 +++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 
clang/test/CodeGenCXX/gh196469-default-member-init-lambda-cleanup.cpp

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9fd8c6a0a5451..cf1ef0a81185f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5710,9 +5710,17 @@ struct EnsureImmediateInvocationInDefaultArgs
 
   // Lambda can only have immediate invocations in the default
   // args of their parameters, which is transformed upon calling the closure.
-  // The body is not a subexpression, so we have nothing to do.
+  // The body is not a subexpression, so we do not transform the lambda
+  // itself. However, the closure object is returned without rebuilding it,
+  // so we must redo the effects building a lambda has on the enclosing
+  // context: any CXXBindTemporaryExpr around it has been dropped by
+  // TransformCXXBindTemporaryExpr, and the enclosing context must be
+  // marked as requiring cleanups for the closure's destructor to be run
+  // at the end of the full-expression.
   // FIXME: Immediate calls in capture initializers should be transformed.
-  ExprResult TransformLambdaExpr(LambdaExpr *E) { return E; }
+  ExprResult TransformLambdaExpr(LambdaExpr *E) {
+    return SemaRef.MaybeBindToTemporary(E);
+  }
   ExprResult TransformBlockExpr(BlockExpr *E) { return E; }
 
   // Make sure we don't rebuild the this pointer as it would
diff --git 
a/clang/test/CodeGenCXX/gh196469-default-member-init-lambda-cleanup.cpp 
b/clang/test/CodeGenCXX/gh196469-default-member-init-lambda-cleanup.cpp
new file mode 100644
index 0000000000000..71857dc449416
--- /dev/null
+++ b/clang/test/CodeGenCXX/gh196469-default-member-init-lambda-cleanup.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm -o - 
%s | FileCheck %s
+
+struct Noisy {
+  Noisy();
+  ~Noisy();
+};
+
+struct Function {
+  template <typename F> Function(F) {}
+};
+
+struct Options {
+  Function function{[noisy = Noisy{}] {}};
+};
+
+Options kOptions{};
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init
+// CHECK: call void @_ZN5NoisyC1Ev
+// CHECK: call void @_ZN8FunctionC1IN7Options8functionMUlvE_EEET_
+// CHECK: call void @_ZN7Options8functionMUlvE_D1Ev
+
+// CHECK-LABEL: define {{.*}} @_ZN7Options8functionMUlvE_D2Ev
+// CHECK: call void @_ZN5NoisyD1Ev

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

Reply via email to