-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang] Fix catching pointers by reference on mingw targets #162546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
For this specific case, when catching a pointer data type, by reference, Clang generates a special code pattern, which directly accesses the exception data by skipping past the `_Unwind_Exception` manually (rather than using the return value of `__cxa_begin_catch`). On most platforms, `_Unwind_Exception` is 32 bytes, but in some configurations it's different. (ARM EHABI is one preexisting case.) In the case of SEH, it's also different - it is 48 bytes in 32 bit mode and 64 bytes in 64 bit mode. Handle this case in `TargetCodeGenInfo::getSizeOfUnwindException`, fixing the code generation for catching pointers by reference. This fixes mstorsjo/llvm-mingw#522.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Martin Storsjö (mstorsjo) ChangesFor this specific case, when catching a pointer data type, by reference, Clang generates a special code pattern, which directly accesses the exception data by skipping past the On most platforms, Handle this case in This fixes mstorsjo/llvm-mingw#522. Full diff: https://github.com/llvm/llvm-project/pull/162546.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 1e58c3f217812..342a3af0ac1ee 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -82,6 +82,8 @@ TargetCodeGenInfo::~TargetCodeGenInfo() = default;
// If someone can figure out a general rule for this, that would be great.
// It's probably just doomed to be platform-dependent, though.
unsigned TargetCodeGenInfo::getSizeOfUnwindException() const {
+ if (getABIInfo().getCodeGenOpts().hasSEHExceptions())
+ return getABIInfo().getDataLayout().getPointerSizeInBits() > 32 ? 64 : 48;
// Verified for:
// x86-64 FreeBSD, Linux, Darwin
// x86-32 FreeBSD, Linux, Darwin
diff --git a/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp b/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
index 4fb977a5367e7..e40b2d7ae43ea 100644
--- a/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
+++ b/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
@@ -3,6 +3,8 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-DARWIN
// RUN: %clang_cc1 -triple arm-unknown-gnueabi -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-EABI
// RUN: %clang_cc1 -triple mipsel-unknown-unknown -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=MIPS
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -fcxx-exceptions -fexceptions -exception-model=seh %s -O2 -o - | FileCheck %s --check-prefix=MINGW-X86-64
+// RUN: %clang_cc1 -triple thumbv7-windows-gnu -emit-llvm -fcxx-exceptions -fexceptions -exception-model=seh %s -O2 -o - | FileCheck %s --check-prefix=MINGW-ARMV7
void foo();
void test() {
@@ -25,9 +27,15 @@ void test() {
// ARM-EABI-NEXT: [[T1:%.*]] = getelementptr i8, ptr [[EXN]], i32 88
// MIPS: [[T0:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXN:%.*]]) [[NUW:#[0-9]+]]
// MIPS-NEXT: [[T1:%.*]] = getelementptr i8, ptr [[EXN]], i32 24
+// MINGW-X86-64: [[T0:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// MINGW-X86-64-NEXT:[[T1:%.*]] = getelementptr i8, ptr [[EXN]], i64 64
+// MINGW-ARMV7: [[T0:%.*]] = tail call arm_aapcs_vfpcc ptr @__cxa_begin_catch(ptr [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// MINGW-ARMV7-NEXT: [[T1:%.*]] = getelementptr i8, ptr [[EXN]], i32 48
// X86-64: attributes [[NUW]] = { nounwind }
// X86-32: attributes [[NUW]] = { nounwind }
// ARM-DARWIN: attributes [[NUW]] = { nounwind }
// ARM-EABI: attributes [[NUW]] = { nounwind }
// MIPS: attributes [[NUW]] = { nounwind }
+// MINGW-X86-64: attributes [[NUW]] = { nounwind }
+// MINGW-ARMV7: attributes [[NUW]] = { nounwind }
|
The header also checks that |
Possibly, yes. I think those ifdefs stem from the corresponding cases in GCC's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this specific case, when catching a pointer data type, by reference, Clang generates a special code pattern, which directly accesses the exception data by skipping past the
_Unwind_Exception
manually (rather than using the return value of__cxa_begin_catch
).On most platforms,
_Unwind_Exception
is 32 bytes, but in some configurations it's different. (ARM EHABI is one preexisting case.) In the case of SEH, it's also different - it is 48 bytes in 32 bit mode and 64 bytes in 64 bit mode. (See the SEH ifdef in_Unwind_Exception
inclang/lib/Headers/unwind.h
.)Handle this case in
TargetCodeGenInfo::getSizeOfUnwindException
, fixing the code generation for catching pointers by reference.This fixes mstorsjo/llvm-mingw#522.