[PATCH] D18479: [CodeGenCXX] Fix ItaniumCXXABI::getAlignmentOfExnObject to return 8-byte alignment on Darwin
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 30 21:47:53 PDT 2016
ahatanak updated this revision to Diff 52171.
ahatanak added a comment.
Thank you for the review, John.
I've updated the patch as per your request. I defined virtual function getExnObjectAlignment instead of adding a ExnObjectAlignment field to TargetInfo since I found that getDefaultAlignForAttributeAligned() can't be called in TargetInfo's constructor to initialize ExnObjectAlignment.
http://reviews.llvm.org/D18479
Files:
include/clang/Basic/TargetInfo.h
lib/Basic/Targets.cpp
lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGenCXX/eh.cpp
Index: test/CodeGenCXX/eh.cpp
===================================================================
--- test/CodeGenCXX/eh.cpp
+++ test/CodeGenCXX/eh.cpp
@@ -448,5 +448,27 @@
}
}
+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 }
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -154,17 +154,9 @@
Address Ptr, QualType ElementType,
const CXXDestructorDecl *Dtor) override;
- /// Itanium says that an _Unwind_Exception has to be "double-word"
- /// aligned (and thus the end of it is also so-aligned), meaning 16
- /// bytes. Of course, that was written for the actual Itanium,
- /// which is a 64-bit platform. Classically, the ABI doesn't really
- /// specify the alignment on other platforms, but in practice
- /// libUnwind declares the struct with __attribute__((aligned)), so
- /// we assume that alignment here. (It's generally 16 bytes, but
- /// some targets overwrite it.)
CharUnits getAlignmentOfExnObject() {
- auto align = CGM.getContext().getTargetDefaultAlignForAttributeAligned();
- return CGM.getContext().toCharUnitsFromBits(align);
+ unsigned Align = CGM.getContext().getTargetInfo().getExnObjectAlignment();
+ return CGM.getContext().toCharUnitsFromBits(Align);
}
void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -262,6 +262,13 @@
bool hasProtectedVisibility() const override {
return false;
}
+
+ unsigned getExnObjectAlignment() const override {
+ // The alignment of an exception object is 8-bytes for darwin since
+ // libc++abi doesn't declare _Unwind_Exception with __attribute__((aligned))
+ // and therefore doesn't guarantee 16-byte alignment.
+ return 64;
+ }
};
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -414,6 +414,19 @@
/// types for the given target.
unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; }
+ /// Return the alignment (in bits) of the thrown exception object.
+ virtual unsigned getExnObjectAlignment() const {
+ /// Itanium says that an _Unwind_Exception has to be "double-word"
+ /// aligned (and thus the end of it is also so-aligned), meaning 16
+ /// bytes. Of course, that was written for the actual Itanium,
+ /// which is a 64-bit platform. Classically, the ABI doesn't really
+ /// specify the alignment on other platforms, but in practice
+ /// libUnwind declares the struct with __attribute__((aligned)), so
+ /// we assume that alignment here. (It's generally 16 bytes, but
+ /// some targets overwrite it.)
+ return getDefaultAlignForAttributeAligned();
+ }
+
/// \brief Return the size of intmax_t and uintmax_t for this target, in bits.
unsigned getIntMaxTWidth() const {
return getTypeWidth(IntMaxType);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18479.52171.patch
Type: text/x-patch
Size: 3853 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160331/a602e6fb/attachment.bin>
More information about the cfe-commits
mailing list