[clang] [CIR] Support Type with PointerRepresentation in CatchParam (PR #173774)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 6 09:45:33 PST 2026
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/173774
>From 0230c3ebc89e4422d70d47ea6efd0ac3b1eaec35 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Sat, 27 Dec 2025 19:26:19 +0100
Subject: [PATCH 1/2] [CIR] Support Type with PointerRepresentation in
CatchParam
---
clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 27 ++++++++-
clang/test/CIR/CodeGen/try-catch-tmp.cpp | 58 +++++++++++++++++++
2 files changed, 82 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 25d2d9f615542..69d4148d74623 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -2333,6 +2333,8 @@ static void initCatchParam(CIRGenFunction &cgf, const VarDecl &catchParam,
Address paramAddr, SourceLocation loc) {
CanQualType catchType =
cgf.cgm.getASTContext().getCanonicalType(catchParam.getType());
+ mlir::Type cirCatchTy = cgf.convertTypeForMem(catchType);
+
// If we're catching by reference, we can just cast the object
// pointer to the appropriate pointer.
if (isa<ReferenceType>(catchType)) {
@@ -2347,14 +2349,33 @@ static void initCatchParam(CIRGenFunction &cgf, const VarDecl &catchParam,
// If the catch type is a pointer type, __cxa_begin_catch returns
// the pointer by value.
if (catchType->hasPointerRepresentation()) {
- cgf.cgm.errorNYI(loc, "initCatchParam: hasPointerRepresentation");
- return;
+ mlir::Value catchParam =
+ callBeginCatch(cgf, cirCatchTy, /*endMightThrow=*/false);
+ switch (catchType.getQualifiers().getObjCLifetime()) {
+ case Qualifiers::OCL_Strong:
+ cgf.cgm.errorNYI(loc,
+ "initCatchParam: PointerRepresentation OCL_Strong");
+ return;
+
+ case Qualifiers::OCL_None:
+ case Qualifiers::OCL_ExplicitNone:
+ case Qualifiers::OCL_Autoreleasing:
+ cgf.getBuilder().createStore(cgf.getLoc(loc), catchParam, paramAddr);
+ return;
+
+ case Qualifiers::OCL_Weak:
+ cgf.cgm.errorNYI(loc, "initCatchParam: PointerRepresentation OCL_Weak");
+ return;
+ }
+
+ llvm_unreachable("bad ownership qualifier!");
}
// Otherwise, it returns a pointer into the exception object.
mlir::Type cirCatchTy = cgf.convertTypeForMem(catchType);
mlir::Value catchParam =
- callBeginCatch(cgf, cgf.getBuilder().getPointerTo(cirCatchTy), false);
+ callBeginCatch(cgf, cgf.getBuilder().getPointerTo(cirCatchTy),
+ /*endMightThrow=*/false);
LValue srcLV = cgf.makeNaturalAlignAddrLValue(catchParam, catchType);
LValue destLV = cgf.makeAddrLValue(paramAddr, catchType);
switch (tek) {
diff --git a/clang/test/CIR/CodeGen/try-catch-tmp.cpp b/clang/test/CIR/CodeGen/try-catch-tmp.cpp
index c98f5d5c5fa28..63a20efb2a9ef 100644
--- a/clang/test/CIR/CodeGen/try-catch-tmp.cpp
+++ b/clang/test/CIR/CodeGen/try-catch-tmp.cpp
@@ -173,6 +173,64 @@ void call_function_inside_try_catch_with_complex_exception_type() {
// OGCG: %[[EXCEPTION_INFO:.*]] = insertvalue { ptr, i32 } %[[TMP_EXCEPTION_INFO]], i32 %[[TMP_EH_TYPE_ID]], 1
// OGCG: resume { ptr, i32 } %[[EXCEPTION_INFO]]
+void call_function_inside_try_catch_with_array_exception_type() {
+ try {
+ division();
+ } catch (int e[]) {
+ }
+}
+
+// CIR: cir.func {{.*}} @_Z56call_function_inside_try_catch_with_array_exception_typev() personality(@__gxx_personality_v0)
+// CIR: cir.scope {
+// CIR: %[[E_ADDR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["e"]
+// CIR: cir.try {
+// CIR: %[[CALL:.*]] = cir.call @_Z8divisionv() : () -> !s32i
+// CIR: cir.yield
+// CIR: } catch [type #cir.global_view<@_ZTIPi> : !cir.ptr<!u8i>] {
+// CIR: %[[CATCH_PARAM:.*]] = cir.catch_param : !cir.ptr<!s32i>
+// CIR: cir.store {{.*}} %[[CATCH_PARAM]], %[[E_ADDR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
+// CIR: cir.yield
+// CIR: } unwind {
+// CIR: cir.resume
+// CIR: }
+// CIR: }
+
+// OGCG: define {{.*}} void @_Z56call_function_inside_try_catch_with_array_exception_typev() #0 personality ptr @__gxx_personality_v0
+// OGCG: %[[EXCEPTION_ADDR:.*]] = alloca ptr, align 8
+// OGCG: %[[EH_TYPE_ID_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[E_ADDR:.*]] = alloca ptr, align 8
+// OGCG: %[[CALL:.*]] = invoke noundef i32 @_Z8divisionv()
+// OGCG: to label %[[INVOKE_NORMAL:.*]] unwind label %[[INVOKE_UNWIND:.*]]
+// OGCG: [[INVOKE_NORMAL]]:
+// OGCG: br label %[[TRY_CONT:.*]]
+// OGCG: [[INVOKE_UNWIND]]:
+// OGCG: %[[LANDING_PAD:.*]] = landingpad { ptr, i32 }
+// OGCG: catch ptr @_ZTIPi
+// OGCG: %[[EXCEPTION:.*]] = extractvalue { ptr, i32 } %[[LANDING_PAD]], 0
+// OGCG: store ptr %[[EXCEPTION]], ptr %[[EXCEPTION_ADDR]], align 8
+// OGCG: %[[EH_TYPE_ID:.*]] = extractvalue { ptr, i32 } %[[LANDING_PAD]], 1
+// OGCG: store i32 %[[EH_TYPE_ID]], ptr %[[EH_TYPE_ID_ADDR]], align 4
+// OGCG: br label %[[CATCH_DISPATCH:.*]]
+// OGCG: [[CATCH_DISPATCH]]:
+// OGCG: %[[TMP_EH_TYPE_ID:.*]] = load i32, ptr %ehselector.slot, align 4
+// OGCG: %[[EH_TYPE_ID:.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIPi)
+// OGCG: %[[TYPE_ID_EQ:.*]] = icmp eq i32 %[[TMP_EH_TYPE_ID]], %[[EH_TYPE_ID]]
+// OGCG: br i1 %[[TYPE_ID_EQ]], label %[[CATCH_EXCEPTION:.*]], label %[[EH_RESUME:.*]]
+// OGCG: [[CATCH_EXCEPTION]]:
+// OGCG: %[[TMP_EXCEPTION:.*]] = load ptr, ptr %[[EXCEPTION_ADDR]], align 8
+// OGCG: %[[BEGIN_CATCH:.*]] = call ptr @__cxa_begin_catch(ptr %[[TMP_EXCEPTION]])
+// OGCG: store ptr %[[BEGIN_CATCH]], ptr %[[E_ADDR]], align 8
+// OGCG: call void @__cxa_end_catch()
+// OGCG: br label %[[TRY_CONT]]
+// OGCG: [[TRY_CONT]]:
+// OGCG: ret void
+// OGCG: [[EH_RESUME]]:
+// OGCG: %[[TMP_EXCEPTION:.*]] = load ptr, ptr %[[EXCEPTION_ADDR]], align 8
+// OGCG: %[[TMP_EH_TYPE_ID:.*]] = load i32, ptr %[[EH_TYPE_ID_ADDR]], align 4
+// OGCG: %[[TMP_EXCEPTION_INFO:.*]] = insertvalue { ptr, i32 } poison, ptr %[[TMP_EXCEPTION]], 0
+// OGCG: %[[EXCEPTION_INFO:.*]] = insertvalue { ptr, i32 } %[[TMP_EXCEPTION_INFO]], i32 %[[TMP_EH_TYPE_ID]], 1
+// OGCG: resume { ptr, i32 } %[[EXCEPTION_INFO]]
+
void call_function_inside_try_catch_with_exception_type_and_catch_all() {
try {
division();
>From ff7838fac5941bd7ae93d1186ac77ce521059a75 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Tue, 6 Jan 2026 18:45:07 +0100
Subject: [PATCH 2/2] Add NYI for OCL_ExplicitNone & OCL_Autoreleasing
---
clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 69d4148d74623..b749336df4068 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -2357,9 +2357,13 @@ static void initCatchParam(CIRGenFunction &cgf, const VarDecl &catchParam,
"initCatchParam: PointerRepresentation OCL_Strong");
return;
- case Qualifiers::OCL_None:
case Qualifiers::OCL_ExplicitNone:
case Qualifiers::OCL_Autoreleasing:
+ cgf.cgm.errorNYI(loc, "initCatchParam: PointerRepresentation "
+ "OCL_ExplicitNone & OCL_Autoreleasing");
+ return;
+
+ case Qualifiers::OCL_None:
cgf.getBuilder().createStore(cgf.getLoc(loc), catchParam, paramAddr);
return;
More information about the cfe-commits
mailing list