[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 23:41:23 PDT 2016


This revision was automatically updated to reflect the committed changes.
Closed by commit rL264998: [CodeGenCXX] Fix ItaniumCXXABI::getAlignmentOfExnObject to return 8-byte (authored by ahatanak).

Changed prior to commit:
  http://reviews.llvm.org/D18479?vs=52171&id=52175#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D18479

Files:
  cfe/trunk/include/clang/Basic/TargetInfo.h
  cfe/trunk/lib/Basic/Targets.cpp
  cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
  cfe/trunk/test/CodeGenCXX/eh.cpp

Index: cfe/trunk/include/clang/Basic/TargetInfo.h
===================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h
+++ cfe/trunk/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);
Index: cfe/trunk/test/CodeGenCXX/eh.cpp
===================================================================
--- cfe/trunk/test/CodeGenCXX/eh.cpp
+++ cfe/trunk/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: cfe/trunk/lib/Basic/Targets.cpp
===================================================================
--- cfe/trunk/lib/Basic/Targets.cpp
+++ cfe/trunk/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: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
+++ cfe/trunk/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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18479.52175.patch
Type: text/x-patch
Size: 3973 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160331/fc7dc2f4/attachment.bin>


More information about the cfe-commits mailing list