summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/eh.cpp
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2016-03-31 06:36:07 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2016-03-31 06:36:07 +0000
commitd3491bd078c477e68d6a3aec1df37c63e255371c (patch)
treef6e481bfc92e88b0493709c66797660af0915ef5 /test/CodeGenCXX/eh.cpp
parent666c01d585e25adf5b5facdf6232800f5fa722ad (diff)
[CodeGenCXX] Fix ItaniumCXXABI::getAlignmentOfExnObject to return 8-byte
alignment on Darwin. Itanium C++ ABI specifies that _Unwind_Exception should be double-word aligned (16B). To conform to the ABI, libraries implementing exception handling declare the struct with __attribute__((aligned)), which aligns the unwindHeader field (and the end of __cxa_exception) to the default target alignment (which is typically 16-bytes). struct __cxa_exception { ... // struct is declared with __attribute__((aligned)). _Unwind_Exception unwindHeader; }; Based on the assumption that _Unwind_Exception is declared with __attribute__((aligned)), ItaniumCXXABI::getAlignmentOfExnObject returns the target default alignment for __attribute__((aligned)). It turns out that libc++abi, which is used on Darwin, doesn't declare the struct with the attribute and therefore doesn't guarantee that unwindHeader is aligned to the alignment specified by the ABI, which in some cases causes the program to crash because of unaligned memory accesses. This commit avoids crashes due to unaligned memory accesses by having getAlignmentOfExnObject return an 8-byte alignment on Darwin. I've only fixed the problem for Darwin, but we should also figure out whether other platforms using libc++abi need similar fixes. rdar://problem/25314277 Differential revision: http://reviews.llvm.org/D18479 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@264998 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/eh.cpp')
-rw-r--r--test/CodeGenCXX/eh.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index b44e8144bb..db0576a1ba 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -448,5 +448,27 @@ namespace test16 {
}
}
+namespace test17 {
+class BaseException {
+private:
+ int a[4];
+public:
+ BaseException() {};
+};
+
+class DerivedException: public BaseException {
+};
+
+int foo() {
+ throw DerivedException();
+ // The alignment passed to memset is 8, not 16, on Darwin.
+
+ // CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
+ // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"*
+ // CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8*
+ // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 8, i1 false)
+}
+}
+
// CHECK: attributes [[NUW]] = { nounwind }
// CHECK: attributes [[NR]] = { noreturn }