From: Yedidya Feldblum Date: Fri, 15 Dec 2017 07:26:47 +0000 (-0800) Subject: Fix folly::max_align_v for Clang on ARMv7 X-Git-Tag: v2017.12.18.00~9 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=8b3a565d0077e92d94c49425850babc65ce1766d;p=folly.git 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 --- 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