Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -353,6 +353,18 @@ # endif // __linux__ #endif +#ifndef _LIBCPP_CXX03_LANG +# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp) +#elif defined(_LIBCPP_COMPILER_CLANG) +# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp) +#else +// This definition is potentially buggy, but it's only taken with GCC in C++03, +// which we barely support anyway. See llvm.org/PR39713 +# define _LIBCPP_ALIGNOF(_Tp) __alignof(_Tp) +#endif + +#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp) + #if defined(_LIBCPP_COMPILER_CLANG) // _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for @@ -367,7 +379,7 @@ # define _ALIGNAS_TYPE(x) alignas(x) # define _ALIGNAS(x) alignas(x) #else -# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) # define _ALIGNAS(x) __attribute__((__aligned__(x))) #endif @@ -494,7 +506,7 @@ #elif defined(_LIBCPP_COMPILER_GCC) #define _ALIGNAS(x) __attribute__((__aligned__(x))) -#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) #define _LIBCPP_NORETURN __attribute__((noreturn)) @@ -607,7 +619,7 @@ #elif defined(_LIBCPP_COMPILER_IBM) #define _ALIGNAS(x) __attribute__((__aligned__(x))) -#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) #define _ATTRIBUTE(x) __attribute__((x)) #define _LIBCPP_NORETURN __attribute__((noreturn)) Index: include/__sso_allocator =================================================================== --- include/__sso_allocator +++ include/__sso_allocator @@ -55,14 +55,14 @@ __allocated_ = true; return (pointer)&buf_; } - return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); + return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) { if (__p == (pointer)&buf_) __allocated_ = false; else - _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), __alignof(_Tp)); + _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); } _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);} Index: include/experimental/coroutine =================================================================== --- include/experimental/coroutine +++ include/experimental/coroutine @@ -214,7 +214,7 @@ _LIBCPP_INLINE_VISIBILITY _Promise& promise() const { return *static_cast<_Promise*>( - __builtin_coro_promise(this->__handle_, __alignof(_Promise), false)); + __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); } public: @@ -254,7 +254,7 @@ coroutine_handle __tmp; __tmp.__handle_ = __builtin_coro_promise( _VSTD::addressof(const_cast<_RawPromise&>(__promise)), - __alignof(_Promise), true); + _LIBCPP_ALIGNOF(_Promise), true); return __tmp; } }; @@ -272,7 +272,7 @@ _LIBCPP_INLINE_VISIBILITY _Promise& promise() const { return *static_cast<_Promise*>( - __builtin_coro_promise(this->__handle_, __alignof(_Promise), false)); + __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); } _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; } Index: include/experimental/memory_resource =================================================================== --- include/experimental/memory_resource +++ include/experimental/memory_resource @@ -98,7 +98,7 @@ // 8.5, memory.resource class _LIBCPP_TYPE_VIS memory_resource { - static const size_t __max_align = alignof(max_align_t); + static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t); // 8.5.2, memory.resource.public public: @@ -190,7 +190,7 @@ " 'n' exceeds maximum supported size"); } return static_cast<_ValueType*>( - __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType)) + __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)) ); } @@ -198,7 +198,7 @@ void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__n <= __max_size(), "deallocate called for size which exceeds max_size()"); - __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType)); + __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)); } template @@ -345,7 +345,7 @@ && is_same::value && is_same::value, ""); - static const size_t _MaxAlign = alignof(max_align_t); + static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t); using _Alloc = typename _CTraits::template rebind_alloc< typename aligned_storage<_MaxAlign, _MaxAlign>::type Index: include/functional =================================================================== --- include/functional +++ include/functional @@ -1872,7 +1872,7 @@ struct __use_small_storage : public _VSTD::integral_constant< bool, sizeof(_Fun) <= sizeof(__policy_storage) && - alignof(_Fun) <= alignof(__policy_storage) && + _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && _VSTD::is_trivially_copy_constructible<_Fun>::value && _VSTD::is_trivially_destructible<_Fun>::value> {}; Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -1811,10 +1811,10 @@ if (__n > max_size()) __throw_length_error("allocator::allocate(size_t n)" " 'n' exceeds maximum supported size"); - return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); + return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT - {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), __alignof(_Tp));} + {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return size_type(~0) / sizeof(_Tp);} #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) @@ -1912,10 +1912,10 @@ if (__n > max_size()) __throw_length_error("allocator::allocate(size_t n)" " 'n' exceeds maximum supported size"); - return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); + return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT - {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), __alignof(_Tp));} + {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return size_type(~0) / sizeof(_Tp);} #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) @@ -2031,7 +2031,7 @@ while (__n > 0) { #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) - if (__is_overaligned_for_new(__alignof(_Tp))) + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { std::align_val_t __al = std::align_val_t(std::alignment_of<_Tp>::value); @@ -2042,7 +2042,7 @@ __n * sizeof(_Tp), nothrow)); } #else - if (__is_overaligned_for_new(__alignof(_Tp))) + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { // Since aligned operator new is unavailable, return an empty // buffer rather than one with invalid alignment. @@ -2066,7 +2066,7 @@ inline _LIBCPP_INLINE_VISIBILITY void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - _VSTD::__libcpp_deallocate_unsized((void*)__p, __alignof(_Tp)); + _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); } #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) @@ -5642,7 +5642,7 @@ struct __temp_value { typedef allocator_traits<_Alloc> _Traits; - typename aligned_storage::type __v; + typename aligned_storage::type __v; _Alloc &__a; _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -1652,7 +1652,7 @@ // alignment_of template struct _LIBCPP_TEMPLATE_VIS alignment_of - : public integral_constant {}; + : public integral_constant {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template @@ -1682,7 +1682,7 @@ template struct __align_type { - static const size_t value = alignment_of<_Tp>::value; + static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp); typedef _Tp type; }; @@ -1815,8 +1815,8 @@ template struct aligned_union { - static const size_t alignment_value = __static_max<__alignof__(_Type0), - __alignof__(_Types)...>::value; + static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), + _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value; static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value; typedef typename aligned_storage<__len, alignment_value>::type type; Index: include/valarray =================================================================== --- include/valarray +++ include/valarray @@ -2740,7 +2740,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(result_type), __alignof(result_type))); + _VSTD::__libcpp_allocate(__n * sizeof(result_type), _LIBCPP_ALIGNOF(result_type))); for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i) ::new (__r.__end_) result_type(__expr_[__i]); } @@ -2758,7 +2758,7 @@ if (__n) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2793,7 +2793,7 @@ if (__n) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2819,7 +2819,7 @@ if (__v.size()) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2857,7 +2857,7 @@ if (__n) { __begin_ = __end_ = static_cast( -_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); +_VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2887,7 +2887,7 @@ if (__n) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2915,7 +2915,7 @@ if (__n) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2945,7 +2945,7 @@ if (__n) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2975,7 +2975,7 @@ if (__n) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -3012,7 +3012,7 @@ { __clear(size()); __begin_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); __end_ = __begin_ + __n; _VSTD::uninitialized_copy(__f, __l, __begin_); } else { @@ -3268,7 +3268,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(+*__p); } @@ -3286,7 +3286,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(-*__p); } @@ -3304,7 +3304,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(~*__p); } @@ -3321,7 +3321,7 @@ { __r.__begin_ = __r.__end_ = - static_cast(_VSTD::__libcpp_allocate(__n * sizeof(bool), __alignof(bool))); + static_cast(_VSTD::__libcpp_allocate(__n * sizeof(bool), _LIBCPP_ALIGNOF(bool))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) bool(!*__p); } @@ -3642,7 +3642,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); const value_type* __sb; value_type* __tb; value_type* __te; @@ -3681,7 +3681,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); __i %= static_cast(__n); const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i; for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s) @@ -3703,7 +3703,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(__f(*__p)); } @@ -3721,7 +3721,7 @@ __r.__begin_ = __r.__end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(__f(*__p)); } @@ -3736,7 +3736,7 @@ { while (__end_ != __begin_) (--__end_)->~value_type(); - _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), __alignof(value_type)); + _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)); __begin_ = __end_ = nullptr; } } @@ -3749,7 +3749,7 @@ if (__n) { __begin_ = __end_ = static_cast( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { Index: test/libcxx/libcpp_alignof.pass.cpp =================================================================== --- test/libcxx/libcpp_alignof.pass.cpp +++ test/libcxx/libcpp_alignof.pass.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Test that _LIBCPP_ALIGNOF acts the same as the C++11 keyword `alignof`, and +// not as the GNU extension `__alignof`. The former returns the minimal required +// alignment for a type, whereas the latter returns the preferred alignment. +// +// See llvm.org/PR39713 + +#include +#include "test_macros.h" + +template +void test() { + static_assert(_LIBCPP_ALIGNOF(T) == std::alignment_of::value, ""); + static_assert(_LIBCPP_ALIGNOF(T) == TEST_ALIGNOF(T), ""); +#if TEST_STD_VER >= 11 + static_assert(_LIBCPP_ALIGNOF(T) == alignof(T), ""); +#endif +#ifdef TEST_COMPILER_CLANG + static_assert(_LIBCPP_ALIGNOF(T) == _Alignof(T), ""); +#endif +} + +int main() { + test(); + test(); + test(); + test(); +} Index: test/std/containers/sequences/array/size_and_alignment.pass.cpp =================================================================== --- test/std/containers/sequences/array/size_and_alignment.pass.cpp +++ test/std/containers/sequences/array/size_and_alignment.pass.cpp @@ -58,8 +58,6 @@ char data[1000]; }; -//static_assert(sizeof(void*) == 4, ""); - int main() { test_type(); test_type(); Index: test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp =================================================================== --- test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp +++ test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp @@ -254,9 +254,6 @@ // Use alignof(std::max_align_t) below to find the max alignment instead of // hardcoding it, because it's different on different platforms. // (For example 8 on arm and 16 on x86.) -#if TEST_STD_VER < 11 -#define alignof __alignof__ -#endif { typedef std::aligned_storage<16>::type T1; #if TEST_STD_VER > 11 @@ -264,7 +261,7 @@ #endif static_assert(std::is_trivial::value, ""); static_assert(std::is_standard_layout::value, ""); - static_assert(std::alignment_of::value == alignof(std::max_align_t), + static_assert(std::alignment_of::value == TEST_ALIGNOF(std::max_align_t), ""); static_assert(sizeof(T1) == 16, ""); } @@ -275,9 +272,9 @@ #endif static_assert(std::is_trivial::value, ""); static_assert(std::is_standard_layout::value, ""); - static_assert(std::alignment_of::value == alignof(std::max_align_t), + static_assert(std::alignment_of::value == TEST_ALIGNOF(std::max_align_t), ""); - static_assert(sizeof(T1) == 16 + alignof(std::max_align_t), ""); + static_assert(sizeof(T1) == 16 + TEST_ALIGNOF(std::max_align_t), ""); } { typedef std::aligned_storage<10>::type T1; Index: test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp =================================================================== --- test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp +++ test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp @@ -19,6 +19,9 @@ template void test_alignment_of() { + const unsigned AlignofResult = TEST_ALIGNOF(T); + static_assert( AlignofResult == A, "Golden value does not match result of alignof keyword"); + static_assert( std::alignment_of::value == AlignofResult, ""); static_assert( std::alignment_of::value == A, ""); static_assert( std::alignment_of::value == A, ""); static_assert( std::alignment_of::value == A, ""); @@ -45,7 +48,10 @@ test_alignment_of(); test_alignment_of(); test_alignment_of(); - test_alignment_of(); + // The test case below is a hack. It's hard to detect what golden value + // we should expect. In most cases it should be 8. But in i386 builds + // with Clang >= 8 or GCC >= 8 the value is '4'. + test_alignment_of(); #if (defined(__ppc__) && !defined(__ppc64__)) test_alignment_of(); // 32-bit PPC has four byte bool #else Index: test/support/test_macros.h =================================================================== --- test/support/test_macros.h +++ test/support/test_macros.h @@ -116,7 +116,11 @@ # define TEST_THROW_SPEC(...) throw(__VA_ARGS__) # endif #else -#define TEST_ALIGNOF(...) __alignof(__VA_ARGS__) +#if defined(TEST_COMPILER_CLANG) +# define TEST_ALIGNOF(...) _Alignof(__VA_ARGS__) +#else +# define TEST_ALIGNOF(...) __alignof(__VA_ARGS__) +#endif #define TEST_ALIGNAS(...) __attribute__((__aligned__(__VA_ARGS__))) #define TEST_CONSTEXPR #define TEST_CONSTEXPR_CXX14