Now that __alignof__ and alignof sometimes disagree it matters which one we use. The standard says that std::alignment_of<T>::value equals alignof(T), so we need to use that.
Change the only uses of alignment_of to use __alignof__ to avoid a change in alignment. PR libstdc++/88119 * include/ext/aligned_buffer.h (__aligned_membuf): Add comment. (__aligned_buffer): Use __alignof__ instead of std::alignment_of. * include/std/type_traits (alignment_of): Use alignof instead of __alignof__. * testsuite/20_util/alignment_of/value.cc: Fix test to check values match alignof not __alignof__, as required by the standard. Tested powercp64le-linux, committed to trunk. This should be changed on gcc-8-branch too.
commit b8b2d1978d67bddd0caf115cff1bf437c6609eef Author: Jonathan Wakely <jwak...@redhat.com> Date: Thu Nov 29 12:07:48 2018 +0000 PR libstdc++/88119 use alignof in std::alignment_of, not __alignof__ Now that __alignof__ and alignof sometimes disagree it matters which one we use. The standard says that std::alignment_of<T>::value equals alignof(T), so we need to use that. Change the only uses of alignment_of to use __alignof__ to avoid a change in alignment. PR libstdc++/88119 * include/ext/aligned_buffer.h (__aligned_membuf): Add comment. (__aligned_buffer): Use __alignof__ instead of std::alignment_of. * include/std/type_traits (alignment_of): Use alignof instead of __alignof__. * testsuite/20_util/alignment_of/value.cc: Fix test to check values match alignof not __alignof__, as required by the standard. diff --git a/libstdc++-v3/include/ext/aligned_buffer.h b/libstdc++-v3/include/ext/aligned_buffer.h index 81fb797723c..2fc8f12e62d 100644 --- a/libstdc++-v3/include/ext/aligned_buffer.h +++ b/libstdc++-v3/include/ext/aligned_buffer.h @@ -49,6 +49,8 @@ namespace __gnu_cxx // Target macro ADJUST_FIELD_ALIGN can produce different alignment for // types when used as class members. __aligned_membuf is intended // for use as a class member, so align the buffer as for a class member. + // Since GCC 8 we could just use alignof(_Tp) instead, but older + // versions of non-GNU compilers might still need this trick. struct _Tp2 { _Tp _M_t; }; alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)]; @@ -86,11 +88,10 @@ namespace __gnu_cxx // This type is still used to avoid an ABI change. template<typename _Tp> struct __aligned_buffer - : std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value> + : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)> { typename - std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>::type - _M_storage; + std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage; __aligned_buffer() = default; diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 60094f9897b..727a5451c56 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -1286,7 +1286,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// alignment_of template<typename _Tp> struct alignment_of - : public integral_constant<std::size_t, __alignof__(_Tp)> { }; + : public integral_constant<std::size_t, alignof(_Tp)> { }; /// rank template<typename> diff --git a/libstdc++-v3/testsuite/20_util/alignment_of/value.cc b/libstdc++-v3/testsuite/20_util/alignment_of/value.cc index 7c46a58bf28..f73008daabd 100644 --- a/libstdc++-v3/testsuite/20_util/alignment_of/value.cc +++ b/libstdc++-v3/testsuite/20_util/alignment_of/value.cc @@ -20,16 +20,22 @@ #include <type_traits> #include <testsuite_tr1.h> +template<typename T> +constexpr bool test() +{ + return __gnu_test::test_property<std::alignment_of, T>(alignof(T)); +} + void test01() { - using std::alignment_of; - using namespace __gnu_test; - - static_assert(test_property<alignment_of, char>(__alignof__(char)), ""); - static_assert(test_property<alignment_of, short>(__alignof__(short)), ""); - static_assert(test_property<alignment_of, int>(__alignof__(int)), ""); - static_assert(test_property<alignment_of, double>(__alignof__(double)), ""); - static_assert(test_property<alignment_of, int[4]>(__alignof__(int[4])), ""); - static_assert(test_property<alignment_of, - ClassType>(__alignof__(ClassType)), ""); + static_assert(test<char>(), ""); + static_assert(test<short>(), ""); + static_assert(test<int>(), ""); + static_assert(test<long>(), ""); + static_assert(test<long long>(), ""); + static_assert(test<float>(), ""); + static_assert(test<double>(), ""); + static_assert(test<long double>(), ""); + static_assert(test<int[4]>(), ""); + static_assert(test<__gnu_test::ClassType>(), ""); }