[clang] [Clang][CodeGen] Fix clang codegen eh cleanup (PR #226743)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 27 17:26:53 PDT 2026
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 <66289396+rdong8 at users.noreply.github.com>
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 bb8cb8a0b0473edd3c975ff0b580ee209a796ba2 Mon Sep 17 00:00:00 2001
From: Richard Dong <66289396+rdong8 at users.noreply.github.com>
Date: Sat, 26 Sep 2026 20:53:54 +0000
Subject: [PATCH 2/2] [Clang][CodeGen] Fix EH cleanup check for compound
literals with destructors
In EmitCompoundLiteralLValue and VisitCompoundLiteralExpr, the code checked
`DtorKind & EHCleanup` to determine whether an exception-handling cleanup
was needed. However, DtorKind is of type QualType::DestructionKind (an enum)
while EHCleanup is CleanupKind (1). Bitwise AND between them inadvertently
tested whether the enum value was odd, skipping EH cleanup for
DK_objc_strong_lifetime (value 2). Use needsEHCleanup(DtorKind) instead.
---
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
More information about the cfe-commits
mailing list