Assume `__cxa_allocate_exception` returns an under-aligned memory on
Darwin if the version of libc++abi isn't new enough to include the fix
in r319123

This patch resurrects r264998, which was committed to work around a bug
in libc++abi that was causing _cxa_allocate_exception to return a memory
that wasn't double-word aligned.

http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160328/154332.html

In addition, this patch makes clang issue a warning if the type of the
thrown object requires an alignment that is larger than the minimum
guaranteed by the target C++ runtime.

rdar://problem/49864414

Differential Revision: https://reviews.llvm.org/D61667

llvm-svn: 360404
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 683fc5b..b256dc6 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -941,6 +941,21 @@
     }
   }
 
+  // Under the Itanium C++ ABI, memory for the exception object is allocated by
+  // the runtime with no ability for the compiler to request additional
+  // alignment. Warn if the exception type requires alignment beyond the minimum
+  // guaranteed by the target C++ runtime.
+  if (Context.getTargetInfo().getCXXABI().isItaniumFamily()) {
+    CharUnits TypeAlign = Context.getTypeAlignInChars(Ty);
+    CharUnits ExnObjAlign = Context.getExnObjectAlignment();
+    if (ExnObjAlign < TypeAlign) {
+      Diag(ThrowLoc, diag::warn_throw_underaligned_obj);
+      Diag(ThrowLoc, diag::note_throw_underaligned_obj)
+          << Ty << (unsigned)TypeAlign.getQuantity()
+          << (unsigned)ExnObjAlign.getQuantity();
+    }
+  }
+
   return false;
 }