https://github.com/rdong8 updated 
https://github.com/llvm/llvm-project/pull/226743

>From 8d8253232a3a7a7c04d177715e325d553426da4a Mon Sep 17 00:00:00 2001
From: Richard Dong <[email protected]>
Date: Wed, 30 Sep 2026 03:48:39 +0000
Subject: [PATCH 1/2] [Clang][CodeGen][test] Add test for compound literals
 with destructors under -fexceptions

Add tests in strong-in-c-struct.m compiling with -fexceptions -fobjc-exceptions 
to verify that exception handling cleanups (invokes and landing pads with 
destructor calls) are emitted for lifetime-extended compound literals with 
destructors.
---
 clang/test/CodeGenObjC/strong-in-c-struct.m | 35 +++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/clang/test/CodeGenObjC/strong-in-c-struct.m 
b/clang/test/CodeGenObjC/strong-in-c-struct.m
index 8b2a161fd9cbb..efe1ac334cb42 100644
--- a/clang/test/CodeGenObjC/strong-in-c-struct.m
+++ b/clang/test/CodeGenObjC/strong-in-c-struct.m
@@ -2,6 +2,8 @@
 
 // RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks  
-fobjc-runtime=ios-11.0 -emit-pch -o %t %s
 // RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks  
-fobjc-runtime=ios-11.0 -include-pch %t -emit-llvm -o - -DUSESTRUCT %s | 
FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks  
-fobjc-runtime=ios-11.0 -fexceptions -fobjc-exceptions -emit-llvm -o - 
-DUSESTRUCT %s | FileCheck %s --check-prefix=CHECK-EH
+
 
 #ifndef HEADER
 #define HEADER
@@ -678,6 +680,14 @@ void test_copy_constructor_VolatileArray(VolatileArray *a) 
{
 
 // CHECK: call void @__destructor_8_s8(ptr %[[_COMPOUNDLITERAL]])
 
+// CHECK-EH: define{{.*}} void @test_compound_literal0(
+// CHECK-EH: invoke void @func(
+// CHECK-EH: to label %{{.*}} unwind label %[[LPAD:.*]]
+// CHECK-EH: [[LPAD]]:
+// CHECK-EH: landingpad
+// CHECK-EH: call void @__destructor_8_s8(
+// CHECK-EH: call void @__destructor_8_s8(
+
 void test_compound_literal0(int c) {
   StrongSmall *p = c ? &(StrongSmall){ 1, 0 } : &(StrongSmall){ 2, 0 };
   func(0);
@@ -736,11 +746,36 @@ void test_compound_literal1(int c) {
 
 // CHECK: call void @__destructor_8_s8(ptr %[[_COMPOUNDLITERAL]])
 
+// CHECK-EH: define{{.*}} void @test_compound_literal2(
+// CHECK-EH: invoke void @func(
+// CHECK-EH: to label %{{.*}} unwind label %[[LPAD:.*]]
+// CHECK-EH: [[LPAD]]:
+// CHECK-EH: landingpad
+// CHECK-EH: call void @__destructor_8_s8(
+// CHECK-EH: call void @__destructor_8_s8(
+
 void test_compound_literal2(int c, StrongSmall *p) {
   *p = c ? (StrongSmall){ 1, 0 } : (StrongSmall){ 2, 0 };
   func(0);
 }
 
+// CHECK: define{{.*}} void @test_compound_literal3(
+// CHECK: call void @func(
+// CHECK: call void @__destructor_8_s8(
+
+// CHECK-EH: define{{.*}} void @test_compound_literal3(
+// CHECK-EH: invoke void @func(
+// CHECK-EH: to label %{{.*}} unwind label %[[LPAD:.*]]
+// CHECK-EH: [[LPAD]]:
+// CHECK-EH: landingpad
+// CHECK-EH: call void @__destructor_8_s8(
+
+void test_compound_literal3(int c) {
+  StrongSmall *p = c ? (StrongSmall[]){ {1, 0}, {2, 0} } : 0;
+  func(0);
+}
+
+
 // CHECK: define{{.*}} void @test_member_access(
 // CHECK: %[[TMP:.*]] = alloca %[[STRUCT_STRONGSMALL]],
 // CHECK: call void @__destructor_8_s8(ptr %[[TMP]])

>From 30867712d1b5e8f3a8b6cc1cefd9d06089b33022 Mon Sep 17 00:00:00 2001
From: Richard Dong <[email protected]>
Date: Wed, 30 Sep 2026 03:48:48 +0000
Subject: [PATCH 2/2] [Clang][CodeGen] Call 3-arg pushLifetimeExtendedDestroy
 (NFC)

NFC for the following reasons:

- `DK_none` and `DK_cxx_destructor` can never reach 
`pushLifetimeExtendedDestroy` at either of the two call sites. `DK_none` is 
filtered out by the `if (...)` check. `DK_cxx_destructor ` only occurs for a 
C++ class, but the code runs only if `!getLangOpts().CPlusPlus`.

- For the other three (`DK_objc_strong_lifetime`, `DK_objc_weak_lifetime`, and 
`DK_nontrivial_c_struct`), the boolean flag controls whether the remaining 
not-yet-destroyed elements of an array get destroyed in `emitArrayDestroy` when 
the destroyer call itself throws when destroying an array element. But the flag 
is irrelevant here because the destroyer functions for the three never throw: 
they are all called via `EmitNounwindRuntimeCall`, which produces a plain 
`call` rather than an `invoke`.
---
 clang/lib/CodeGen/CGExpr.cpp    | 4 +---
 clang/lib/CodeGen/CGExprAgg.cpp | 5 ++---
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 4a481c01f6a68..cf67ea7982b0d 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -6173,9 +6173,7 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const 
CompoundLiteralExpr *E){
   // scope in C.
   if (!getLangOpts().CPlusPlus)
     if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
-      pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr,
-                                  E->getType(), getDestroyer(DtorKind),
-                                  DtorKind & EHCleanup);
+      pushLifetimeExtendedDestroy(DtorKind, DeclPtr, E->getType());
 
   return Result;
 }
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index ff0ed1473d7df..73c6301c5d585 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -792,9 +792,8 @@ void 
AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
 
   if (Destruct)
     if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
-      CGF.pushLifetimeExtendedDestroy(
-          CGF.getCleanupKind(DtorKind), Slot.getAddress(), E->getType(),
-          CGF.getDestroyer(DtorKind), DtorKind & EHCleanup);
+      CGF.pushLifetimeExtendedDestroy(DtorKind, Slot.getAddress(),
+                                      E->getType());
 }
 
 /// Attempt to look through various unimportant expressions to find a

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

Reply via email to