https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/184442
Implement init support for reference type in the init catch param >From 50066362a9bab8a1da19b7720cc9882f7d30d9cc Mon Sep 17 00:00:00 2001 From: Amr Hesham <[email protected]> Date: Tue, 3 Mar 2026 21:50:46 +0100 Subject: [PATCH] [CIR] Implement reference type in init catch param --- clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 18 +++++- clang/test/CIR/CodeGen/try-catch-tmp.cpp | 64 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index f195b9325a41c..b8516f85e5051 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -2385,7 +2385,23 @@ static void initCatchParam(CIRGenFunction &cgf, mlir::Value ehToken, // If we're catching by reference, we can just cast the object // pointer to the appropriate pointer. if (isa<ReferenceType>(catchType)) { - cgf.cgm.errorNYI(loc, "initCatchParam: ReferenceType"); + QualType caughtType = cast<ReferenceType>(catchType)->getPointeeType(); + bool endCatchMightThrow = caughtType->isRecordType(); + + mlir::Value adjustedExn = + callBeginCatch(cgf, ehToken, cirCatchTy, endCatchMightThrow); + + // We have no way to tell the personality function that we're + // catching by reference, so if we're catching a pointer, + // __cxa_begin_catch will actually return that pointer by value. + if (isa<PointerType>(caughtType)) { + cgf.cgm.errorNYI(loc, "initCatchParam: catching a pointer"); + return; + } + + mlir::Value exnCast = + cgf.getBuilder().createBitcast(adjustedExn, cirCatchTy); + cgf.getBuilder().createStore(cgf.getLoc(loc), exnCast, paramAddr); return; } diff --git a/clang/test/CIR/CodeGen/try-catch-tmp.cpp b/clang/test/CIR/CodeGen/try-catch-tmp.cpp index 5cb60aaf6b2cc..405f54c41885c 100644 --- a/clang/test/CIR/CodeGen/try-catch-tmp.cpp +++ b/clang/test/CIR/CodeGen/try-catch-tmp.cpp @@ -119,6 +119,70 @@ void call_function_inside_try_catch_with_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_ref_exception_type() { + try { + division(); + } catch (int &ref) { + } +} + +// CIR: cir.func {{.*}} @_Z54call_function_inside_try_catch_with_ref_exception_typev() personality(@__gxx_personality_v0) +// CIR: cir.scope { +// CIR: %[[EXCEPTION_ADDR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["ref", const] +// CIR: cir.try { +// CIR: %[[CALL:.*]] = cir.call @_Z8divisionv() +// CIR: cir.yield +// CIR: } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] (%{{.*}}: !cir.eh_token {{.*}}) { +// CIR: %[[CATCH_TOKEN:.*]], %[[EXN_PTR:.*]] = cir.begin_catch %{{.*}} : !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>) +// CIR: cir.cleanup.scope { +// CIR: cir.store {{.*}} %[[EXN_PTR]], %[[EXCEPTION_ADDR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>> +// CIR: cir.yield +// CIR: } cleanup all { +// CIR: cir.end_catch %[[CATCH_TOKEN]] : !cir.catch_token +// CIR: cir.yield +// CIR: } +// CIR: cir.yield +// CIR: } unwind (%{{.*}}: !cir.eh_token {{.*}}) { +// CIR: cir.resume %{{.*}} : !cir.eh_token +// CIR: } +// CIR: } + +// OGCG: define {{.*}} void @_Z54call_function_inside_try_catch_with_ref_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 @_ZTIi +// OGCG: %[[EXCEPTION:.*]] = extractvalue { ptr, i32 } %[[LANDING_PAD]], 0 +// OGCG: store ptr %1, 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 %[[EH_TYPE_ID_ADDR]], align 4 +// OGCG: %[[EH_TYPE_ID:.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) +// 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_complex_exception_type() { try { division(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
