diff options
| author | Eric Fiselier <eric@efcs.ca> | 2019-04-30 18:44:45 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2019-04-30 18:44:45 +0000 |
| commit | 71aa67506b94a299843a6123009d2677ffe329d2 (patch) | |
| tree | 071754d10774efcd1d71530aeb381764c687de5e /libcxx | |
| parent | ea349f3ef592c053272ff0053c60eca704028e6e (diff) | |
| download | bcm5719-llvm-71aa67506b94a299843a6123009d2677ffe329d2.tar.gz bcm5719-llvm-71aa67506b94a299843a6123009d2677ffe329d2.zip | |
Support overaligned types in `aligned_storage`.
Summary:
The current implementation of aligned storage was written before we had `alignas`, so it used a list of builtin types to force the alignment. But this doesn't work overaligned requests.
This patch adds a fallback case supporting over-alignment. It only affects case that were previously ill-formed.
Reviewers: rsmith, ldionne, dlj, mclow.lists
Reviewed By: mclow.lists
Subscribers: mclow.lists, dexonsmith, libcxx-commits
Differential Revision: https://reviews.llvm.org/D61301
llvm-svn: 359596
Diffstat (limited to 'libcxx')
| -rw-r--r-- | libcxx/include/type_traits | 6 | ||||
| -rw-r--r-- | libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp | 8 |
2 files changed, 12 insertions, 2 deletions
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index a0bdb2b418e..d17bd090427 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -1768,6 +1768,9 @@ typedef __nat > > > > > > > > > > __all_types; +template <size_t _Align> +struct _ALIGNAS(_Align) __fallback_overaligned {}; + template <class _TL, size_t _Align> struct __find_pod; template <class _Hp, size_t _Align> @@ -1776,7 +1779,7 @@ struct __find_pod<__type_list<_Hp, __nat>, _Align> typedef typename conditional< _Align == _Hp::value, typename _Hp::type, - void + __fallback_overaligned<_Align> >::type type; }; @@ -1813,7 +1816,6 @@ template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::valu struct _LIBCPP_TEMPLATE_VIS aligned_storage { typedef typename __find_pod<__all_types, _Align>::type _Aligner; - static_assert(!is_void<_Aligner>::value, ""); union type { _Aligner __align; diff --git a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp index 0b4aac31580..e7615329598 100644 --- a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp @@ -285,6 +285,14 @@ int main(int, char**) static_assert(std::alignment_of<T1>::value == 8, ""); static_assert(sizeof(T1) == 16, ""); } + { + const int Align = 65536; + typedef typename std::aligned_storage<1, Align>::type T1; + static_assert(std::is_trivial<T1>::value, ""); + static_assert(std::is_standard_layout<T1>::value, ""); + static_assert(std::alignment_of<T1>::value == Align, ""); + static_assert(sizeof(T1) == Align, ""); + } return 0; } |

