From: Jonathan Wakely Date: Wed, 26 Jun 2024 11:40:51 +0000 (+0100) Subject: libstdc++: Simplify class templates X-Git-Tag: basepoints/gcc-16~7840 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac8c61b62e71ffdcaebfd4cfc03f58fe542855dd;p=thirdparty%2Fgcc.git libstdc++: Simplify class templates As noted in a comment, the __gnu_cxx::__aligned_membuf class template can be simplified, because alignof(T) and alignas(T) use the correct alignment for a data member. That's true since GCC 8 and Clang 8. The EDG front end (as used by Intel icc, aka "Intel C++ Compiler Classic") does not implement the PR c++/69560 change, so keep using the old implementation when __EDG__ is defined, to avoid an ABI change for icc. For __gnu_cxx::__aligned_buffer all supported compilers agree on the value of __alignof__(T), but we can still simplify it by removing the dependency on std::aligned_storage. Add a test that checks that the aligned buffer types have the expected alignment, so that we can tell if changes like this affect their ABI properties. libstdc++-v3/ChangeLog: * include/ext/aligned_buffer.h (__aligned_membuf): Use alignas(T) directly instead of defining a struct and using 9its alignment. (__aligned_buffer): Remove use of std::aligned_storage. * testsuite/abi/aligned_buffers.cc: New test. --- diff --git a/libstdc++-v3/include/ext/aligned_buffer.h b/libstdc++-v3/include/ext/aligned_buffer.h index 26b36609fa53..9c2c628e54a9 100644 --- a/libstdc++-v3/include/ext/aligned_buffer.h +++ b/libstdc++-v3/include/ext/aligned_buffer.h @@ -49,11 +49,15 @@ 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. + // 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; @@ -81,8 +85,6 @@ namespace __gnu_cxx template 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 , , // and , but ideally they would use __aligned_membuf @@ -90,10 +92,9 @@ namespace __gnu_cxx // This type is still used to avoid an ABI change. template struct __aligned_buffer - : std::aligned_storage { - typename - std::aligned_storage::type _M_storage; + // Using __alignof__ gives the alignment for a complete object. + alignas(__alignof__(_Tp)) unsigned char _M_storage[sizeof(_Tp)]; __aligned_buffer() = default; @@ -120,7 +121,6 @@ namespace __gnu_cxx _M_ptr() const noexcept { return static_cast(_M_addr()); } }; -#pragma GCC diagnostic pop #endif } // namespace diff --git a/libstdc++-v3/testsuite/abi/aligned_buffers.cc b/libstdc++-v3/testsuite/abi/aligned_buffers.cc new file mode 100644 index 000000000000..b4b8ea139700 --- /dev/null +++ b/libstdc++-v3/testsuite/abi/aligned_buffers.cc @@ -0,0 +1,42 @@ +// { dg-do compile { target c++11 } } + +// Check alignment of the buffer types used for uninitialized storage. + +#include + +template using membuf = __gnu_cxx::__aligned_membuf; +template using objbuf = __gnu_cxx::__aligned_buffer; + +template +constexpr bool +check_alignof_membuf() +{ + return alignof(membuf) == alignof(T) + && __alignof__(membuf) == alignof(T); +} + +template +constexpr bool +check_alignof_objbuf() +{ +#if _GLIBCXX_INLINE_VERSION + // For the gnu-versioned-namespace ABI __aligned_buffer == __aligned_membuf. + return check_alignof_membuf(); +#else + return alignof(objbuf) == __alignof__(T) + && __alignof__(objbuf) == __alignof__(T); +#endif +} + +struct S { long long l; }; +struct alignas(128) X { char x; }; +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" );