https://github.com/rdong8 updated https://github.com/llvm/llvm-project/pull/226743
>From 87850e035d00eb000086cab024d15a50ffb55044 Mon Sep 17 00:00:00 2001 From: Richard Dong <[email protected]> Date: Mon, 28 Sep 2026 00:24:40 +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 a6d8e7944e1adc6d7a4bcd25795f66ec9c168340 Mon Sep 17 00:00:00 2001 From: Richard Dong <[email protected]> Date: Sat, 26 Sep 2026 20:53:54 +0000 Subject: [PATCH 2/2] [Clang][CodeGen] Fix type mismatch in pushLifetimeExtendedDestroy for compound literals (NFC) In EmitCompoundLiteralLValue and VisitCompoundLiteralExpr, the code passed `DtorKind & EHCleanup` for the `useEHCleanupForArray` argument of pushLifetimeExtendedDestroy. DtorKind is of type QualType::DestructionKind (an enum) while EHCleanup is an enumerator of CleanupKind (0x1). Bitwise AND between them was a type mismatch that inadvertently tested whether the DestructionKind enum value was odd. Use needsEHCleanup(DtorKind) (or CGF.needsEHCleanup(DtorKind)) instead, matching the convention used elsewhere in CodeGen. This is NFC because: 1. For non-array compound literals, useEHCleanupForArray is unused (only the first argument, cleanupKind, determines whether the compound literal itself receives an EH cleanup, and that already used getCleanupKind(DtorKind)). 2. For array compound literals, useEHCleanupForArray only pushes a partial cleanup during element destruction if an individual element destructor can throw. The types where the check changed (DK_objc_strong_lifetime and DK_nontrivial_c_struct) have non-throwing destructors, so no exception edges are emitted and the partial cleanup is never triggered. --- clang/lib/CodeGen/CGExpr.cpp | 2 +- clang/lib/CodeGen/CGExprAgg.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 4a481c01f6a68..a555e8e851819 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -6175,7 +6175,7 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){ if (QualType::DestructionKind DtorKind = E->getType().isDestructedType()) pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr, E->getType(), getDestroyer(DtorKind), - DtorKind & EHCleanup); + needsEHCleanup(DtorKind)); return Result; } diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index ff0ed1473d7df..f393e75ead1d6 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -794,7 +794,7 @@ void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { if (QualType::DestructionKind DtorKind = E->getType().isDestructedType()) CGF.pushLifetimeExtendedDestroy( CGF.getCleanupKind(DtorKind), Slot.getAddress(), E->getType(), - CGF.getDestroyer(DtorKind), DtorKind & EHCleanup); + CGF.getDestroyer(DtorKind), CGF.needsEHCleanup(DtorKind)); } /// 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
