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>(), "");
 }

Reply via email to