Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ unsigned TargetCodeGenInfo::getSizeOfUnwindException() const {
// PowerPC Linux
// ARM Darwin (*not* EABI)
// AArch64 Linux
return 32;
unsigned PointerSize = Info->getTarget().getPointerWidth(LangAS::Default) / 8;
return PointerSize > 8 ? 4 * PointerSize : 32;
}

bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args,
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/Targets/Mips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class MIPSTargetCodeGenInfo : public CommonCheriTargetCodeGenInfo {
MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32, CodeGenModule &CGM)
: CommonCheriTargetCodeGenInfo(
std::make_unique<MipsABIInfo>(CGT, IsO32, CGM)),
SizeOfUnwindException(IsO32 ? 24 : 32) {}
SizeOfUnwindException(
IsO32 ? 24 : TargetCodeGenInfo::getSizeOfUnwindException()) {}

int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
return 29;
Expand Down
143 changes: 143 additions & 0 deletions clang/test/CodeGenCXX/cheri/size-of-unwind-exception.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// RUN: %cheri128_purecap_cc1 -fexceptions -fcxx-exceptions -disable-O0-optnone -emit-llvm %s -o - \
// RUN: | opt -S -passes=mem2reg | FileCheck %s --check-prefix=CHECK-MIPS
// RUN: %riscv32_cheri_purecap_cc1 -fexceptions -fcxx-exceptions -disable-O0-optnone -emit-llvm %s -o - \
// RUN: | opt -S -passes=mem2reg | FileCheck %s --check-prefix=CHECK-RV32
// RUN: %riscv64_cheri_purecap_cc1 -fexceptions -fcxx-exceptions -disable-O0-optnone -emit-llvm %s -o - \
// RUN: | opt -S -passes=mem2reg | FileCheck %s --check-prefix=CHECK-RV64

/// Check that we use the correct size for struct _Unwind_Exception

void foo();
void bar(int *&);

// CHECK-MIPS-LABEL: define dso_local void @_Z3bazv
// CHECK-MIPS-SAME: () addrspace(200) #[[ATTR0:[0-9]+]] personality ptr addrspace(200) @__gxx_personality_v0 {
// CHECK-MIPS-NEXT: entry:
// CHECK-MIPS-NEXT: invoke void @_Z3foov()
// CHECK-MIPS-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-MIPS: invoke.cont:
// CHECK-MIPS-NEXT: br label [[TRY_CONT:%.*]]
// CHECK-MIPS: lpad:
// CHECK-MIPS-NEXT: [[TMP0:%.*]] = landingpad { ptr addrspace(200), i32 }
// CHECK-MIPS-NEXT: catch ptr addrspace(200) @_ZTIPi
// CHECK-MIPS-NEXT: [[TMP1:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP0]], 0
// CHECK-MIPS-NEXT: [[TMP2:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP0]], 1
// CHECK-MIPS-NEXT: br label [[CATCH_DISPATCH:%.*]]
// CHECK-MIPS: catch.dispatch:
// CHECK-MIPS-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p200(ptr addrspace(200) @_ZTIPi) #[[ATTR3:[0-9]+]]
// CHECK-MIPS-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
// CHECK-MIPS-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
// CHECK-MIPS: catch:
// CHECK-MIPS-NEXT: [[TMP4:%.*]] = call ptr addrspace(200) @__cxa_begin_catch(ptr addrspace(200) [[TMP1]]) #[[ATTR3]]
// CHECK-MIPS-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr addrspace(200) [[TMP1]], i32 64
// CHECK-MIPS-NEXT: invoke void @_Z3barRPi(ptr addrspace(200) noundef nonnull align 16 dereferenceable(16) [[TMP5]])
// CHECK-MIPS-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
// CHECK-MIPS: invoke.cont2:
// CHECK-MIPS-NEXT: call void @__cxa_end_catch() #[[ATTR3]]
// CHECK-MIPS-NEXT: br label [[TRY_CONT]]
// CHECK-MIPS: try.cont:
// CHECK-MIPS-NEXT: ret void
// CHECK-MIPS: lpad1:
// CHECK-MIPS-NEXT: [[TMP6:%.*]] = landingpad { ptr addrspace(200), i32 }
// CHECK-MIPS-NEXT: cleanup
// CHECK-MIPS-NEXT: [[TMP7:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP6]], 0
// CHECK-MIPS-NEXT: [[TMP8:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP6]], 1
// CHECK-MIPS-NEXT: call void @__cxa_end_catch() #[[ATTR3]]
// CHECK-MIPS-NEXT: br label [[EH_RESUME]]
// CHECK-MIPS: eh.resume:
// CHECK-MIPS-NEXT: [[EHSELECTOR_SLOT_0:%.*]] = phi i32 [ [[TMP8]], [[LPAD1]] ], [ [[TMP2]], [[CATCH_DISPATCH]] ]
// CHECK-MIPS-NEXT: [[EXN_SLOT_0:%.*]] = phi ptr addrspace(200) [ [[TMP7]], [[LPAD1]] ], [ [[TMP1]], [[CATCH_DISPATCH]] ]
// CHECK-MIPS-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr addrspace(200), i32 } poison, ptr addrspace(200) [[EXN_SLOT_0]], 0
// CHECK-MIPS-NEXT: [[LPAD_VAL5:%.*]] = insertvalue { ptr addrspace(200), i32 } [[LPAD_VAL]], i32 [[EHSELECTOR_SLOT_0]], 1
// CHECK-MIPS-NEXT: resume { ptr addrspace(200), i32 } [[LPAD_VAL5]]
//
// CHECK-RV32-LABEL: define dso_local void @_Z3bazv
// CHECK-RV32-SAME: () addrspace(200) #[[ATTR0:[0-9]+]] personality ptr addrspace(200) @__gxx_personality_v0 {
// CHECK-RV32-NEXT: entry:
// CHECK-RV32-NEXT: invoke void @_Z3foov()
// CHECK-RV32-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-RV32: invoke.cont:
// CHECK-RV32-NEXT: br label [[TRY_CONT:%.*]]
// CHECK-RV32: lpad:
// CHECK-RV32-NEXT: [[TMP0:%.*]] = landingpad { ptr addrspace(200), i32 }
// CHECK-RV32-NEXT: catch ptr addrspace(200) @_ZTIPi
// CHECK-RV32-NEXT: [[TMP1:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP0]], 0
// CHECK-RV32-NEXT: [[TMP2:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP0]], 1
// CHECK-RV32-NEXT: br label [[CATCH_DISPATCH:%.*]]
// CHECK-RV32: catch.dispatch:
// CHECK-RV32-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p200(ptr addrspace(200) @_ZTIPi) #[[ATTR3:[0-9]+]]
// CHECK-RV32-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
// CHECK-RV32-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
// CHECK-RV32: catch:
// CHECK-RV32-NEXT: [[TMP4:%.*]] = call ptr addrspace(200) @__cxa_begin_catch(ptr addrspace(200) [[TMP1]]) #[[ATTR3]]
// CHECK-RV32-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr addrspace(200) [[TMP1]], i32 32
// CHECK-RV32-NEXT: invoke void @_Z3barRPi(ptr addrspace(200) noundef nonnull align 8 dereferenceable(8) [[TMP5]])
// CHECK-RV32-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
// CHECK-RV32: invoke.cont2:
// CHECK-RV32-NEXT: call void @__cxa_end_catch() #[[ATTR3]]
// CHECK-RV32-NEXT: br label [[TRY_CONT]]
// CHECK-RV32: try.cont:
// CHECK-RV32-NEXT: ret void
// CHECK-RV32: lpad1:
// CHECK-RV32-NEXT: [[TMP6:%.*]] = landingpad { ptr addrspace(200), i32 }
// CHECK-RV32-NEXT: cleanup
// CHECK-RV32-NEXT: [[TMP7:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP6]], 0
// CHECK-RV32-NEXT: [[TMP8:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP6]], 1
// CHECK-RV32-NEXT: call void @__cxa_end_catch() #[[ATTR3]]
// CHECK-RV32-NEXT: br label [[EH_RESUME]]
// CHECK-RV32: eh.resume:
// CHECK-RV32-NEXT: [[EHSELECTOR_SLOT_0:%.*]] = phi i32 [ [[TMP8]], [[LPAD1]] ], [ [[TMP2]], [[CATCH_DISPATCH]] ]
// CHECK-RV32-NEXT: [[EXN_SLOT_0:%.*]] = phi ptr addrspace(200) [ [[TMP7]], [[LPAD1]] ], [ [[TMP1]], [[CATCH_DISPATCH]] ]
// CHECK-RV32-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr addrspace(200), i32 } poison, ptr addrspace(200) [[EXN_SLOT_0]], 0
// CHECK-RV32-NEXT: [[LPAD_VAL5:%.*]] = insertvalue { ptr addrspace(200), i32 } [[LPAD_VAL]], i32 [[EHSELECTOR_SLOT_0]], 1
// CHECK-RV32-NEXT: resume { ptr addrspace(200), i32 } [[LPAD_VAL5]]
//
// CHECK-RV64-LABEL: define dso_local void @_Z3bazv
// CHECK-RV64-SAME: () addrspace(200) #[[ATTR0:[0-9]+]] personality ptr addrspace(200) @__gxx_personality_v0 {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: invoke void @_Z3foov()
// CHECK-RV64-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
// CHECK-RV64: invoke.cont:
// CHECK-RV64-NEXT: br label [[TRY_CONT:%.*]]
// CHECK-RV64: lpad:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = landingpad { ptr addrspace(200), i32 }
// CHECK-RV64-NEXT: catch ptr addrspace(200) @_ZTIPi
// CHECK-RV64-NEXT: [[TMP1:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP0]], 0
// CHECK-RV64-NEXT: [[TMP2:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP0]], 1
// CHECK-RV64-NEXT: br label [[CATCH_DISPATCH:%.*]]
// CHECK-RV64: catch.dispatch:
// CHECK-RV64-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p200(ptr addrspace(200) @_ZTIPi) #[[ATTR3:[0-9]+]]
// CHECK-RV64-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
// CHECK-RV64-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
// CHECK-RV64: catch:
// CHECK-RV64-NEXT: [[TMP4:%.*]] = call ptr addrspace(200) @__cxa_begin_catch(ptr addrspace(200) [[TMP1]]) #[[ATTR3]]
// CHECK-RV64-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr addrspace(200) [[TMP1]], i32 64
// CHECK-RV64-NEXT: invoke void @_Z3barRPi(ptr addrspace(200) noundef nonnull align 16 dereferenceable(16) [[TMP5]])
// CHECK-RV64-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1:%.*]]
// CHECK-RV64: invoke.cont2:
// CHECK-RV64-NEXT: call void @__cxa_end_catch() #[[ATTR3]]
// CHECK-RV64-NEXT: br label [[TRY_CONT]]
// CHECK-RV64: try.cont:
// CHECK-RV64-NEXT: ret void
// CHECK-RV64: lpad1:
// CHECK-RV64-NEXT: [[TMP6:%.*]] = landingpad { ptr addrspace(200), i32 }
// CHECK-RV64-NEXT: cleanup
// CHECK-RV64-NEXT: [[TMP7:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP6]], 0
// CHECK-RV64-NEXT: [[TMP8:%.*]] = extractvalue { ptr addrspace(200), i32 } [[TMP6]], 1
// CHECK-RV64-NEXT: call void @__cxa_end_catch() #[[ATTR3]]
// CHECK-RV64-NEXT: br label [[EH_RESUME]]
// CHECK-RV64: eh.resume:
// CHECK-RV64-NEXT: [[EHSELECTOR_SLOT_0:%.*]] = phi i32 [ [[TMP8]], [[LPAD1]] ], [ [[TMP2]], [[CATCH_DISPATCH]] ]
// CHECK-RV64-NEXT: [[EXN_SLOT_0:%.*]] = phi ptr addrspace(200) [ [[TMP7]], [[LPAD1]] ], [ [[TMP1]], [[CATCH_DISPATCH]] ]
// CHECK-RV64-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr addrspace(200), i32 } poison, ptr addrspace(200) [[EXN_SLOT_0]], 0
// CHECK-RV64-NEXT: [[LPAD_VAL5:%.*]] = insertvalue { ptr addrspace(200), i32 } [[LPAD_VAL]], i32 [[EHSELECTOR_SLOT_0]], 1
// CHECK-RV64-NEXT: resume { ptr addrspace(200), i32 } [[LPAD_VAL5]]
//
void baz() {
try {
foo();
} catch (int *&p) {
bar(p);
}
}
Loading