https://github.com/im-lunex updated https://github.com/llvm/llvm-project/pull/224680
From 1f39fd518ea82aef0f20086329151e975b4c6464 Mon Sep 17 00:00:00 2001 From: im-lunex <[email protected]> Date: Fri, 18 Sep 2026 23:01:46 +0600 Subject: [PATCH 1/3] add test for the rest of the cases --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 11 ++++--- .../CodeGenCXX/exception-addrspace-ms.cpp | 31 +++++++++++++++++++ clang/test/CodeGenCXX/exceptions.cpp | 12 +++++++ 3 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenCXX/exception-addrspace-ms.cpp diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index c17813140b10f7..5c3832d915ac07 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -5032,7 +5032,8 @@ static void InitCatchParam(CodeGenFunction &CGF, // Create the temporary and write the adjusted pointer into it. Address ExnPtrTmp = CGF.CreateTempAlloca(PtrTy, CGF.getPointerAlign(), "exn.byref.tmp"); - llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); + llvm::Value *Casted = + CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(AdjustedExn, PtrTy); CGF.Builder.CreateStore(Casted, ExnPtrTmp); // Bind the reference to the temporary. @@ -5040,8 +5041,8 @@ static void InitCatchParam(CodeGenFunction &CGF, } } - llvm::Value *ExnCast = - CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref"); + llvm::Value *ExnCast = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + AdjustedExn, LLVMCatchTy, "exn.byref"); CGF.Builder.CreateStore(ExnCast, ParamAddr); return; } @@ -5054,8 +5055,8 @@ static void InitCatchParam(CodeGenFunction &CGF, // If the catch type is a pointer type, __cxa_begin_catch returns // the pointer by value. if (CatchType->hasPointerRepresentation()) { - llvm::Value *CastExn = - CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted"); + llvm::Value *CastExn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + AdjustedExn, LLVMCatchTy, "exn.casted"); switch (CatchType.getQualifiers().getObjCLifetime()) { case Qualifiers::OCL_Strong: diff --git a/clang/test/CodeGenCXX/exception-addrspace-ms.cpp b/clang/test/CodeGenCXX/exception-addrspace-ms.cpp new file mode 100644 index 00000000000000..0130abe32e977b --- /dev/null +++ b/clang/test/CodeGenCXX/exception-addrspace-ms.cpp @@ -0,0 +1,31 @@ +// Test for issue - (https://github.com/llvm/llvm-project/issues/222931) +// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck -check-prefix=CHECK-PTR32 %s +// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck -check-prefix=CHECK-AS270-BYREF %s +// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck -check-prefix=CHECK-AS270-REF %s + +void sink_ptr32(int); + +void test_ptr32() { + try { throw (int * __ptr32)0; } catch (int * __ptr32 p) { sink_ptr32(*p); } +} + +// CHECK-PTR32: %exn.casted = addrspacecast ptr %{{.*}} to ptr addrspace(270) + +typedef int __attribute__((address_space(270))) as270_int; +void sink_as270(as270_int &); + +void test_byref() { + try { throw (as270_int)0; } catch (as270_int &p) { sink_as270(p); } +} + +// CHECK-AS270-BYREF: %exn.byref = addrspacecast ptr {{.*}} to ptr addrspace(270) + +struct S2 {}; +typedef S2 __attribute__((address_space(270))) *PtrRec; +void sink_ptrrec(PtrRec &); + +void test_ptrrec() { + try { throw (PtrRec)0; } catch (PtrRec &p) { sink_ptrrec(p); } +} + +// CHECK-AS270-REF: store ptr addrspace(270) %{{.*}}, ptr %exn.byref.tmp, align 8 \ No newline at end of file diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp index 6c920d71867095..7986aefb1eafd4 100644 --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -623,3 +623,15 @@ void test(int c) { } // CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind {{.*}} } + +// Test for issue - (https://github.com/llvm/llvm-project/issues/222931) +// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK-AS1 %s + +typedef int __attribute__((address_space(1))) *as1_int_ptr; +void sink_as1(int); + +void test_as1() { + try { throw (as1_int_ptr)0; } catch (as1_int_ptr p) { sink_as1(*p); } +} + +// CHECK-AS1: %exn.casted = addrspacecast ptr %{{.*}} to ptr addrspace(1) From c222765a1f500d6f65710458c63409ce51277c1d Mon Sep 17 00:00:00 2001 From: im-lunex <[email protected]> Date: Tue, 22 Sep 2026 21:58:50 +0600 Subject: [PATCH 2/3] improve test and separate those --- .../CodeGenCXX/catch-address-space-ptr.cpp | 257 ++++++++++++++++++ .../CodeGenCXX/exception-addrspace-ms.cpp | 31 --- clang/test/CodeGenCXX/exceptions.cpp | 14 - 3 files changed, 257 insertions(+), 45 deletions(-) create mode 100644 clang/test/CodeGenCXX/catch-address-space-ptr.cpp delete mode 100644 clang/test/CodeGenCXX/exception-addrspace-ms.cpp diff --git a/clang/test/CodeGenCXX/catch-address-space-ptr.cpp b/clang/test/CodeGenCXX/catch-address-space-ptr.cpp new file mode 100644 index 00000000000000..64b5ca8ec75ee3 --- /dev/null +++ b/clang/test/CodeGenCXX/catch-address-space-ptr.cpp @@ -0,0 +1,257 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck %s + +// Issue #222931: Verify that catching pointers in non-zero address spaces +// generates addrspacecast instead of invalid bitcast. + +void sink_ptr32(int); + +// CHECK-LABEL: define dso_local void @_Z10test_ptr32v( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[P:%.*]] = alloca ptr addrspace(270), align 4 +// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 4) #[[ATTR3:[0-9]+]] +// CHECK-NEXT: store ptr addrspace(270) null, ptr [[EXCEPTION]], align 16 +// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIPU10ptr32_sptri, ptr null) #[[ATTR4:[0-9]+]] +// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] +// CHECK: [[LPAD]]: +// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: catch ptr @_ZTIPU10ptr32_sptri +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 +// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 +// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] +// CHECK: [[CATCH_DISPATCH]]: +// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIPU10ptr32_sptri) #[[ATTR3]] +// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] +// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] +// CHECK: [[CATCH]]: +// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] +// CHECK-NEXT: [[EXN_CASTED:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(270) +// CHECK-NEXT: store ptr addrspace(270) [[EXN_CASTED]], ptr [[P]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(270), ptr [[P]], align 4 +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr addrspace(270) [[TMP5]], align 4 +// CHECK-NEXT: invoke void @_Z10sink_ptr32i(i32 [[TMP6]]) +// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] +// CHECK: [[INVOKE_CONT]]: +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[TRY_CONT:.*]] +// CHECK: [[TRY_CONT]]: +// CHECK-NEXT: ret void +// CHECK: [[LPAD1]]: +// CHECK-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: cleanup +// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 +// CHECK-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 +// CHECK-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[EH_RESUME]] +// CHECK: [[EH_RESUME]]: +// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 +// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 +// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] +// CHECK: [[UNREACHABLE]]: +// CHECK-NEXT: unreachable +// +void test_ptr32() { + try { throw (int * __ptr32)0; } catch (int * __ptr32 p) { sink_ptr32(*p); } +} + +typedef int __attribute__((address_space(270))) as270_int; +void sink_as270(as270_int &); + +// CHECK-LABEL: define dso_local void @_Z10test_byrefv( +// CHECK-SAME: ) #[[ATTR0]] personality ptr @__gxx_personality_v0 { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[P:%.*]] = alloca ptr addrspace(270), align 4 +// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 4) #[[ATTR3]] +// CHECK-NEXT: store i32 0, ptr [[EXCEPTION]], align 16 +// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIi, ptr null) #[[ATTR4]] +// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] +// CHECK: [[LPAD]]: +// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: catch ptr @_ZTIi +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 +// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 +// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] +// CHECK: [[CATCH_DISPATCH]]: +// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #[[ATTR3]] +// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] +// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] +// CHECK: [[CATCH]]: +// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] +// CHECK-NEXT: [[EXN_BYREF:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(270) +// CHECK-NEXT: store ptr addrspace(270) [[EXN_BYREF]], ptr [[P]], align 4 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(270), ptr [[P]], align 4, !align [[META1:![0-9]+]] +// CHECK-NEXT: invoke void @_Z10sink_as270RU5AS270i(ptr addrspace(270) align 4 dereferenceable(4) [[TMP5]]) +// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] +// CHECK: [[INVOKE_CONT]]: +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[TRY_CONT:.*]] +// CHECK: [[TRY_CONT]]: +// CHECK-NEXT: ret void +// CHECK: [[LPAD1]]: +// CHECK-NEXT: [[TMP6:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: cleanup +// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0 +// CHECK-NEXT: store ptr [[TMP7]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1 +// CHECK-NEXT: store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[EH_RESUME]] +// CHECK: [[EH_RESUME]]: +// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 +// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 +// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] +// CHECK: [[UNREACHABLE]]: +// CHECK-NEXT: unreachable +// +void test_byref() { + try { throw (as270_int)0; } catch (as270_int &p) { sink_as270(p); } +} + +struct S2 {}; +typedef S2 __attribute__((address_space(270))) *PtrRec; +void sink_ptrrec(PtrRec &); + +// CHECK-LABEL: define dso_local void @_Z11test_ptrrecv( +// CHECK-SAME: ) #[[ATTR0]] personality ptr @__gxx_personality_v0 { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[P:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[EXN_BYREF_TMP:%.*]] = alloca ptr addrspace(270), align 8 +// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 4) #[[ATTR3]] +// CHECK-NEXT: store ptr addrspace(270) null, ptr [[EXCEPTION]], align 16 +// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIPU5AS2702S2, ptr null) #[[ATTR4]] +// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] +// CHECK: [[LPAD]]: +// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: catch ptr @_ZTIPU5AS2702S2 +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 +// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 +// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] +// CHECK: [[CATCH_DISPATCH]]: +// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIPU5AS2702S2) #[[ATTR3]] +// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] +// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] +// CHECK: [[CATCH]]: +// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] +// CHECK-NEXT: [[TMP5:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(270) +// CHECK-NEXT: store ptr addrspace(270) [[TMP5]], ptr [[EXN_BYREF_TMP]], align 8 +// CHECK-NEXT: store ptr [[EXN_BYREF_TMP]], ptr [[P]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META2:![0-9]+]], !align [[META1]] +// CHECK-NEXT: invoke void @_Z11sink_ptrrecRPU5AS2702S2(ptr nonnull align 4 dereferenceable(4) [[TMP6]]) +// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] +// CHECK: [[INVOKE_CONT]]: +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[TRY_CONT:.*]] +// CHECK: [[TRY_CONT]]: +// CHECK-NEXT: ret void +// CHECK: [[LPAD1]]: +// CHECK-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: cleanup +// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 +// CHECK-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 +// CHECK-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[EH_RESUME]] +// CHECK: [[EH_RESUME]]: +// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 +// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 +// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] +// CHECK: [[UNREACHABLE]]: +// CHECK-NEXT: unreachable +// +void test_ptrrec() { + try { throw (PtrRec)0; } catch (PtrRec &p) { sink_ptrrec(p); } +} + +typedef int __attribute__((address_space(1))) *as1_int_ptr; +void sink_as1(int); + +// CHECK-LABEL: define dso_local void @_Z8test_as1v( +// CHECK-SAME: ) #[[ATTR0]] personality ptr @__gxx_personality_v0 { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[P:%.*]] = alloca ptr addrspace(1), align 8 +// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 8) #[[ATTR3]] +// CHECK-NEXT: store ptr addrspace(1) null, ptr [[EXCEPTION]], align 16 +// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIPU3AS1i, ptr null) #[[ATTR4]] +// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] +// CHECK: [[LPAD]]: +// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: catch ptr @_ZTIPU3AS1i +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 +// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 +// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] +// CHECK: [[CATCH_DISPATCH]]: +// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIPU3AS1i) #[[ATTR3]] +// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] +// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] +// CHECK: [[CATCH]]: +// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] +// CHECK-NEXT: [[EXN_CASTED:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1) +// CHECK-NEXT: store ptr addrspace(1) [[EXN_CASTED]], ptr [[P]], align 8 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[P]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr addrspace(1) [[TMP5]], align 4 +// CHECK-NEXT: invoke void @_Z8sink_as1i(i32 [[TMP6]]) +// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] +// CHECK: [[INVOKE_CONT]]: +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[TRY_CONT:.*]] +// CHECK: [[TRY_CONT]]: +// CHECK-NEXT: ret void +// CHECK: [[LPAD1]]: +// CHECK-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } +// CHECK-NEXT: cleanup +// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 +// CHECK-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 +// CHECK-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] +// CHECK-NEXT: br label %[[EH_RESUME]] +// CHECK: [[EH_RESUME]]: +// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 +// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 +// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] +// CHECK: [[UNREACHABLE]]: +// CHECK-NEXT: unreachable +// +void test_as1() { + try { throw (as1_int_ptr)0; } catch (as1_int_ptr p) { sink_as1(*p); } +} +//. +// CHECK: [[META1]] = !{i64 4} +// CHECK: [[META2]] = !{} +//. diff --git a/clang/test/CodeGenCXX/exception-addrspace-ms.cpp b/clang/test/CodeGenCXX/exception-addrspace-ms.cpp deleted file mode 100644 index 0130abe32e977b..00000000000000 --- a/clang/test/CodeGenCXX/exception-addrspace-ms.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// Test for issue - (https://github.com/llvm/llvm-project/issues/222931) -// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck -check-prefix=CHECK-PTR32 %s -// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck -check-prefix=CHECK-AS270-BYREF %s -// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck -check-prefix=CHECK-AS270-REF %s - -void sink_ptr32(int); - -void test_ptr32() { - try { throw (int * __ptr32)0; } catch (int * __ptr32 p) { sink_ptr32(*p); } -} - -// CHECK-PTR32: %exn.casted = addrspacecast ptr %{{.*}} to ptr addrspace(270) - -typedef int __attribute__((address_space(270))) as270_int; -void sink_as270(as270_int &); - -void test_byref() { - try { throw (as270_int)0; } catch (as270_int &p) { sink_as270(p); } -} - -// CHECK-AS270-BYREF: %exn.byref = addrspacecast ptr {{.*}} to ptr addrspace(270) - -struct S2 {}; -typedef S2 __attribute__((address_space(270))) *PtrRec; -void sink_ptrrec(PtrRec &); - -void test_ptrrec() { - try { throw (PtrRec)0; } catch (PtrRec &p) { sink_ptrrec(p); } -} - -// CHECK-AS270-REF: store ptr addrspace(270) %{{.*}}, ptr %exn.byref.tmp, align 8 \ No newline at end of file diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp index 7986aefb1eafd4..858d8dcccc764b 100644 --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -621,17 +621,3 @@ void test(int c) { } } - -// CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind {{.*}} } - -// Test for issue - (https://github.com/llvm/llvm-project/issues/222931) -// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK-AS1 %s - -typedef int __attribute__((address_space(1))) *as1_int_ptr; -void sink_as1(int); - -void test_as1() { - try { throw (as1_int_ptr)0; } catch (as1_int_ptr p) { sink_as1(*p); } -} - -// CHECK-AS1: %exn.casted = addrspacecast ptr %{{.*}} to ptr addrspace(1) From fc905cb5f227cae40ab537764b7c956863d4afb5 Mon Sep 17 00:00:00 2001 From: im-lunex <[email protected]> Date: Wed, 23 Sep 2026 14:50:37 +0600 Subject: [PATCH 3/3] [Sema] we dont have the runtimes support for cross-address-space conversions yet. soo reject those kind of pointers with non-default address space in Sema insted --- .../clang/Basic/DiagnosticSemaKinds.td | 5 +- clang/lib/CodeGen/ItaniumCXXABI.cpp | 11 +- clang/lib/Sema/SemaDeclCXX.cpp | 7 + clang/lib/Sema/SemaExprCXX.cpp | 8 + .../CodeGenCXX/catch-address-space-ptr.cpp | 257 ------------------ clang/test/CodeGenCXX/exceptions.cpp | 2 + clang/test/Sema/throw-address-space.cpp | 18 ++ 7 files changed, 44 insertions(+), 264 deletions(-) delete mode 100644 clang/test/CodeGenCXX/catch-address-space-ptr.cpp create mode 100644 clang/test/Sema/throw-address-space.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 825d17f49790c6..13053db72e4e2e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8907,7 +8907,10 @@ def warn_cdtor_function_try_handler_mem_expr : Warning< "%select{constructor|destructor}0 function try block">, InGroup<Exceptions>; def err_throw_object_throwing_dtor : Error< "cannot throw object of type %0 with a potentially-throwing destructor">; - +def err_throw_address_space_qualified_ptr : Error< + "cannot throw pointer with address space %0">; +def err_catch_address_space_qualified_ptr : Error< + "cannot catch pointer with address space">; let CategoryName = "Lambda Issue" in { def err_capture_more_than_once : Error< "%0 can appear only once in a capture list">; diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 5c3832d915ac07..1e644cedc31767 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -5032,8 +5032,7 @@ static void InitCatchParam(CodeGenFunction &CGF, // Create the temporary and write the adjusted pointer into it. Address ExnPtrTmp = CGF.CreateTempAlloca(PtrTy, CGF.getPointerAlign(), "exn.byref.tmp"); - llvm::Value *Casted = - CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(AdjustedExn, PtrTy); + llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); CGF.Builder.CreateStore(Casted, ExnPtrTmp); // Bind the reference to the temporary. @@ -5041,8 +5040,8 @@ static void InitCatchParam(CodeGenFunction &CGF, } } - llvm::Value *ExnCast = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - AdjustedExn, LLVMCatchTy, "exn.byref"); + llvm::Value *ExnCast = + CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref"); CGF.Builder.CreateStore(ExnCast, ParamAddr); return; } @@ -5055,8 +5054,8 @@ static void InitCatchParam(CodeGenFunction &CGF, // If the catch type is a pointer type, __cxa_begin_catch returns // the pointer by value. if (CatchType->hasPointerRepresentation()) { - llvm::Value *CastExn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - AdjustedExn, LLVMCatchTy, "exn.casted"); + llvm::Value *CastExn = + CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted"); switch (CatchType.getQualifiers().getObjCLifetime()) { case Qualifiers::OCL_Strong: diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index ea628f29d8a005..f6fdd0eee5f766 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -17504,6 +17504,13 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, Invalid = true; } + // reject trowing of pointers with non-default address space cause runtimes + // dosn't have support for cross-address-space conversions yet; + if (!Invalid && Mode == 1 && BaseType.getAddressSpace() != LangAS::Default) { + Diag(Loc, diag::err_catch_address_space_qualified_ptr) << ExDeclType; + Invalid = true; + } + if (!Invalid && Mode != 1 && BaseType->isSizelessType()) { Diag(Loc, diag::err_catch_sizeless) << (Mode == 2 ? 1 : 0) << BaseType; Invalid = true; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index deb7bdd09fdc7d..a66b6a8c28dc12 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -981,6 +981,14 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, isPointer = true; } + // reject trowing of pointers with Non-default address space cause runtimes + // dosen't have support for cross-address-space conversions yet; + if (isPointer && Ty.getAddressSpace() != LangAS::Default) { + Diag(ThrowLoc, diag::err_throw_address_space_qualified_ptr) + << E->getType() << E->getSourceRange(); + return true; + } + // Cannot throw WebAssembly reference type. if (Ty.isWebAssemblyReferenceType()) { Diag(ThrowLoc, diag::err_wasm_reftype_tc) << 0 << E->getSourceRange(); diff --git a/clang/test/CodeGenCXX/catch-address-space-ptr.cpp b/clang/test/CodeGenCXX/catch-address-space-ptr.cpp deleted file mode 100644 index 64b5ca8ec75ee3..00000000000000 --- a/clang/test/CodeGenCXX/catch-address-space-ptr.cpp +++ /dev/null @@ -1,257 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 -// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fms-extensions | FileCheck %s - -// Issue #222931: Verify that catching pointers in non-zero address spaces -// generates addrspacecast instead of invalid bitcast. - -void sink_ptr32(int); - -// CHECK-LABEL: define dso_local void @_Z10test_ptr32v( -// CHECK-SAME: ) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[P:%.*]] = alloca ptr addrspace(270), align 4 -// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 4) #[[ATTR3:[0-9]+]] -// CHECK-NEXT: store ptr addrspace(270) null, ptr [[EXCEPTION]], align 16 -// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIPU10ptr32_sptri, ptr null) #[[ATTR4:[0-9]+]] -// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] -// CHECK: [[LPAD]]: -// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: catch ptr @_ZTIPU10ptr32_sptri -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 -// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 -// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] -// CHECK: [[CATCH_DISPATCH]]: -// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIPU10ptr32_sptri) #[[ATTR3]] -// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] -// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] -// CHECK: [[CATCH]]: -// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] -// CHECK-NEXT: [[EXN_CASTED:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(270) -// CHECK-NEXT: store ptr addrspace(270) [[EXN_CASTED]], ptr [[P]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(270), ptr [[P]], align 4 -// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr addrspace(270) [[TMP5]], align 4 -// CHECK-NEXT: invoke void @_Z10sink_ptr32i(i32 [[TMP6]]) -// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] -// CHECK: [[INVOKE_CONT]]: -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[TRY_CONT:.*]] -// CHECK: [[TRY_CONT]]: -// CHECK-NEXT: ret void -// CHECK: [[LPAD1]]: -// CHECK-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: cleanup -// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 -// CHECK-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 -// CHECK-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[EH_RESUME]] -// CHECK: [[EH_RESUME]]: -// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 -// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 -// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] -// CHECK: [[UNREACHABLE]]: -// CHECK-NEXT: unreachable -// -void test_ptr32() { - try { throw (int * __ptr32)0; } catch (int * __ptr32 p) { sink_ptr32(*p); } -} - -typedef int __attribute__((address_space(270))) as270_int; -void sink_as270(as270_int &); - -// CHECK-LABEL: define dso_local void @_Z10test_byrefv( -// CHECK-SAME: ) #[[ATTR0]] personality ptr @__gxx_personality_v0 { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[P:%.*]] = alloca ptr addrspace(270), align 4 -// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 4) #[[ATTR3]] -// CHECK-NEXT: store i32 0, ptr [[EXCEPTION]], align 16 -// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIi, ptr null) #[[ATTR4]] -// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] -// CHECK: [[LPAD]]: -// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: catch ptr @_ZTIi -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 -// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 -// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] -// CHECK: [[CATCH_DISPATCH]]: -// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #[[ATTR3]] -// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] -// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] -// CHECK: [[CATCH]]: -// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] -// CHECK-NEXT: [[EXN_BYREF:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(270) -// CHECK-NEXT: store ptr addrspace(270) [[EXN_BYREF]], ptr [[P]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(270), ptr [[P]], align 4, !align [[META1:![0-9]+]] -// CHECK-NEXT: invoke void @_Z10sink_as270RU5AS270i(ptr addrspace(270) align 4 dereferenceable(4) [[TMP5]]) -// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] -// CHECK: [[INVOKE_CONT]]: -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[TRY_CONT:.*]] -// CHECK: [[TRY_CONT]]: -// CHECK-NEXT: ret void -// CHECK: [[LPAD1]]: -// CHECK-NEXT: [[TMP6:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: cleanup -// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0 -// CHECK-NEXT: store ptr [[TMP7]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1 -// CHECK-NEXT: store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[EH_RESUME]] -// CHECK: [[EH_RESUME]]: -// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 -// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 -// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] -// CHECK: [[UNREACHABLE]]: -// CHECK-NEXT: unreachable -// -void test_byref() { - try { throw (as270_int)0; } catch (as270_int &p) { sink_as270(p); } -} - -struct S2 {}; -typedef S2 __attribute__((address_space(270))) *PtrRec; -void sink_ptrrec(PtrRec &); - -// CHECK-LABEL: define dso_local void @_Z11test_ptrrecv( -// CHECK-SAME: ) #[[ATTR0]] personality ptr @__gxx_personality_v0 { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[P:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[EXN_BYREF_TMP:%.*]] = alloca ptr addrspace(270), align 8 -// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 4) #[[ATTR3]] -// CHECK-NEXT: store ptr addrspace(270) null, ptr [[EXCEPTION]], align 16 -// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIPU5AS2702S2, ptr null) #[[ATTR4]] -// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] -// CHECK: [[LPAD]]: -// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: catch ptr @_ZTIPU5AS2702S2 -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 -// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 -// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] -// CHECK: [[CATCH_DISPATCH]]: -// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIPU5AS2702S2) #[[ATTR3]] -// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] -// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] -// CHECK: [[CATCH]]: -// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] -// CHECK-NEXT: [[TMP5:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(270) -// CHECK-NEXT: store ptr addrspace(270) [[TMP5]], ptr [[EXN_BYREF_TMP]], align 8 -// CHECK-NEXT: store ptr [[EXN_BYREF_TMP]], ptr [[P]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META2:![0-9]+]], !align [[META1]] -// CHECK-NEXT: invoke void @_Z11sink_ptrrecRPU5AS2702S2(ptr nonnull align 4 dereferenceable(4) [[TMP6]]) -// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] -// CHECK: [[INVOKE_CONT]]: -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[TRY_CONT:.*]] -// CHECK: [[TRY_CONT]]: -// CHECK-NEXT: ret void -// CHECK: [[LPAD1]]: -// CHECK-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: cleanup -// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 -// CHECK-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 -// CHECK-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[EH_RESUME]] -// CHECK: [[EH_RESUME]]: -// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 -// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 -// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] -// CHECK: [[UNREACHABLE]]: -// CHECK-NEXT: unreachable -// -void test_ptrrec() { - try { throw (PtrRec)0; } catch (PtrRec &p) { sink_ptrrec(p); } -} - -typedef int __attribute__((address_space(1))) *as1_int_ptr; -void sink_as1(int); - -// CHECK-LABEL: define dso_local void @_Z8test_as1v( -// CHECK-SAME: ) #[[ATTR0]] personality ptr @__gxx_personality_v0 { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 -// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// CHECK-NEXT: [[P:%.*]] = alloca ptr addrspace(1), align 8 -// CHECK-NEXT: [[EXCEPTION:%.*]] = call ptr @__cxa_allocate_exception(i64 8) #[[ATTR3]] -// CHECK-NEXT: store ptr addrspace(1) null, ptr [[EXCEPTION]], align 16 -// CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIPU3AS1i, ptr null) #[[ATTR4]] -// CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]] -// CHECK: [[LPAD]]: -// CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: catch ptr @_ZTIPU3AS1i -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 -// CHECK-NEXT: store ptr [[TMP1]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 -// CHECK-NEXT: store i32 [[TMP2]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: br label %[[CATCH_DISPATCH:.*]] -// CHECK: [[CATCH_DISPATCH]]: -// CHECK-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIPU3AS1i) #[[ATTR3]] -// CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]] -// CHECK-NEXT: br i1 [[MATCHES]], label %[[CATCH:.*]], label %[[EH_RESUME:.*]] -// CHECK: [[CATCH]]: -// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]] -// CHECK-NEXT: [[EXN_CASTED:%.*]] = addrspacecast ptr [[TMP4]] to ptr addrspace(1) -// CHECK-NEXT: store ptr addrspace(1) [[EXN_CASTED]], ptr [[P]], align 8 -// CHECK-NEXT: [[TMP5:%.*]] = load ptr addrspace(1), ptr [[P]], align 8 -// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr addrspace(1) [[TMP5]], align 4 -// CHECK-NEXT: invoke void @_Z8sink_as1i(i32 [[TMP6]]) -// CHECK-NEXT: to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD1:.*]] -// CHECK: [[INVOKE_CONT]]: -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[TRY_CONT:.*]] -// CHECK: [[TRY_CONT]]: -// CHECK-NEXT: ret void -// CHECK: [[LPAD1]]: -// CHECK-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } -// CHECK-NEXT: cleanup -// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 -// CHECK-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 -// CHECK-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: call void @__cxa_end_catch() #[[ATTR3]] -// CHECK-NEXT: br label %[[EH_RESUME]] -// CHECK: [[EH_RESUME]]: -// CHECK-NEXT: [[EXN2:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 -// CHECK-NEXT: [[SEL3:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 -// CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN2]], 0 -// CHECK-NEXT: [[LPAD_VAL4:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL3]], 1 -// CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL4]] -// CHECK: [[UNREACHABLE]]: -// CHECK-NEXT: unreachable -// -void test_as1() { - try { throw (as1_int_ptr)0; } catch (as1_int_ptr p) { sink_as1(*p); } -} -//. -// CHECK: [[META1]] = !{i64 4} -// CHECK: [[META2]] = !{} -//. diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp index 858d8dcccc764b..6c920d71867095 100644 --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -621,3 +621,5 @@ void test(int c) { } } + +// CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind {{.*}} } diff --git a/clang/test/Sema/throw-address-space.cpp b/clang/test/Sema/throw-address-space.cpp new file mode 100644 index 00000000000000..8b70e1c13bff2c --- /dev/null +++ b/clang/test/Sema/throw-address-space.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -fms-extensions -verify %s + +// test for issue (https://github.com/llvm/llvm-project/issues/222931) + +// Reject throwing/catching pointers with non-default address spaces in Sema because +// runtimes dont yet support for cross-address-space pointer conversions + +void test_throw() { + throw (int * __ptr32)0; // expected-error {{cannot throw pointer with address space}} + throw (int __attribute__((address_space(1))) *)0; // expected-error {{cannot throw pointer with address space}} +} + +void test_catch() { + try { + } catch (int * __ptr32 p) { // expected-error {{cannot catch pointer with address space}} + } catch (int __attribute__((address_space(1))) * p) { // expected-error {{cannot catch pointer with address space}} + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
