From 8b3a565d0077e92d94c49425850babc65ce1766d Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Thu, 14 Dec 2017 23:26:47 -0800 Subject: [PATCH] Fix folly::max_align_v for Clang on ARMv7 Summary: [Folly] Fix `folly::max_align_v` for Clang on ARMv7. There is some problem with computing the correct result of `alignof` for a compound `union` POD type, because why wouldn't there be. The result *should* just be the max of the `alignof` of the type of each field if each field is default aligned - but not on some platforms! So we must compute the max directly. Reviewed By: mzlee, Orvid Differential Revision: D6573548 fbshipit-source-id: 512a255fda64795104d71fde14372befa3bf41e4 --- folly/lang/Align.h | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/folly/lang/Align.h b/folly/lang/Align.h index 8b878d40..4f0564dc 100644 --- a/folly/lang/Align.h +++ b/folly/lang/Align.h @@ -22,22 +22,34 @@ namespace folly { namespace detail { -union max_align_ { - std::max_align_t mat; - long double ld; - double d; - float f; - long long int lli; - long int li; - int i; - short int si; - bool b; - char c; - char16_t c16; - char32_t c32; - wchar_t wc; - std::nullptr_t n; +// Implemented this way because of a bug in Clang for ARMv7, which gives the +// wrong result for `alignof` a `union` with a field of each scalar type. +constexpr size_t max_align_(std::size_t a) { + return a; +} +template +constexpr std::size_t max_align_(std::size_t a, std::size_t e, Es... es) { + return !(a < e) ? a : max_align_(e, es...); +} +template +struct max_align_t_ { + static constexpr std::size_t value = max_align_(0u, alignof(Ts)...); }; +using max_align_v_ = max_align_t_< + long double, + double, + float, + long long int, + long int, + int, + short int, + bool, + char, + char16_t, + char32_t, + wchar_t, + void*, + std::max_align_t>; } // namespace detail @@ -73,7 +85,7 @@ union max_align_ { // crashes on 32-bit iOS apps that use `double`. // // Apple's allocation reference: http://bit.ly/malloc-small -constexpr std::size_t max_align_v = alignof(detail::max_align_); +constexpr std::size_t max_align_v = detail::max_align_v_::value; struct alignas(max_align_v) max_align_t {}; } // namespace folly -- 2.34.1