// 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.
+ // Since GCC 8 we can just use alignas(_Tp) to get the right alignment.
+#ifdef __EDG__
+ // The EDG front end does not implement the PR c++/69560 alignof change.
struct _Tp2 { _Tp _M_t; };
-
- alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
+ alignas(__alignof__(_Tp2::_M_t))
+#else
+ alignas(_Tp)
+#endif
+ unsigned char _M_storage[sizeof(_Tp)];
__aligned_membuf() = default;
template<typename _Tp>
using __aligned_buffer = __aligned_membuf<_Tp>;
#else
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
// Similar to __aligned_membuf but aligned for complete objects, not members.
// This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h>
// and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf
// This type is still used to avoid an ABI change.
template<typename _Tp>
struct __aligned_buffer
- : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>
{
- typename
- std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage;
+ // Using __alignof__ gives the alignment for a complete object.
+ alignas(__alignof__(_Tp)) unsigned char _M_storage[sizeof(_Tp)];
__aligned_buffer() = default;
_M_ptr() const noexcept
{ return static_cast<const _Tp*>(_M_addr()); }
};
-#pragma GCC diagnostic pop
#endif
} // namespace
--- /dev/null
+// { dg-do compile { target c++11 } }
+
+// Check alignment of the buffer types used for uninitialized storage.
+
+#include <ext/aligned_buffer.h>
+
+template<typename T> using membuf = __gnu_cxx::__aligned_membuf<T>;
+template<typename T> using objbuf = __gnu_cxx::__aligned_buffer<T>;
+
+template<typename T>
+constexpr bool
+check_alignof_membuf()
+{
+ return alignof(membuf<T>) == alignof(T)
+ && __alignof__(membuf<T>) == alignof(T);
+}
+
+template<typename T>
+constexpr bool
+check_alignof_objbuf()
+{
+#if _GLIBCXX_INLINE_VERSION
+ // For the gnu-versioned-namespace ABI __aligned_buffer == __aligned_membuf.
+ return check_alignof_membuf<T>();
+#else
+ return alignof(objbuf<T>) == __alignof__(T)
+ && __alignof__(objbuf<T>) == __alignof__(T);
+#endif
+}
+
+struct S { long long l; };
+struct alignas(128) X { char x; };
+static_assert( check_alignof_membuf<int>(), "membuf<int>" );
+static_assert( check_alignof_membuf<long long>(), "membuf<long long>" );
+static_assert( check_alignof_membuf<void*>(), "membuf<void*>" );
+static_assert( check_alignof_membuf<S>(), "membuf<S>" );
+static_assert( check_alignof_membuf<X>(), "membuf<X>" );
+static_assert( check_alignof_objbuf<int>(), "objbuf<int>" );
+static_assert( check_alignof_objbuf<long long>(), "objbuf<long long>" );
+static_assert( check_alignof_objbuf<void*>(), "objbuf<void*>" );
+static_assert( check_alignof_objbuf<S>(), "objbuf<S>" );
+static_assert( check_alignof_objbuf<X>(), "objbuf<X>" );