diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-10-24 16:29:41 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-10-24 16:29:41 +0100 |
commit | 75c6a925dab5b7af9ab47c10906cb0e140261cc2 (patch) | |
tree | 7118ea8e1c16b8855187cdfe10af00f75cff4891 | |
parent | bf037872d3cd0928bea72335dc7a138a0b2fb43c (diff) | |
download | gcc-75c6a925dab5b7af9ab47c10906cb0e140261cc2.zip gcc-75c6a925dab5b7af9ab47c10906cb0e140261cc2.tar.gz gcc-75c6a925dab5b7af9ab47c10906cb0e140261cc2.tar.bz2 |
Revert ABI changes to std::allocator in C++20
The recent C++20 changes to remove the std::allocator<void> explicit
specialization and the destructor in the std::allocator primary template
change the result of some is_trivially_xxx type traits. To avoid those
changes, this patch restores the explicit specialization and the
destructor.
In order to meet the C++20 requirements the std::allocator<void>
explicit specialization must provide the same interface as the primary
template (except for the unusable allocate and deallocate member
functions) and the destructor in the primary template must be constexpr.
* include/bits/allocator.h (allocator<void>): Restore the explicit
specialization for C++20, but make its API consistent with the primary
template.
(allocator::~allocator()): Restore the destructor for C++20, but make
it constexpr.
* testsuite/20_util/allocator/rebind_c++20.cc: Check allocator<void>.
* testsuite/20_util/allocator/requirements/typedefs_c++20.cc: Likewise.
* testsuite/20_util/allocator/void.cc: Check that constructors and
destructors are trivial. Check for converting constructor in C++20.
* testsuite/ext/malloc_allocator/variadic_construct.cc: Simplify
dejagnu target selector.
* testsuite/ext/new_allocator/variadic_construct.cc: Likewise.
From-SVN: r277410
7 files changed, 64 insertions, 10 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 13e834b..0ae347e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,18 @@ 2019-10-24 Jonathan Wakely <jwakely@redhat.com> + * include/bits/allocator.h (allocator<void>): Restore the explicit + specialization for C++20, but make its API consistent with the primary + template. + (allocator::~allocator()): Restore the destructor for C++20, but make + it constexpr. + * testsuite/20_util/allocator/rebind_c++20.cc: Check allocator<void>. + * testsuite/20_util/allocator/requirements/typedefs_c++20.cc: Likewise. + * testsuite/20_util/allocator/void.cc: Check that constructors and + destructors are trivial. Check for converting constructor in C++20. + * testsuite/ext/malloc_allocator/variadic_construct.cc: Simplify + dejagnu target selector. + * testsuite/ext/new_allocator/variadic_construct.cc: Likewise. + * include/experimental/executor (__use_future_ct, use_future_t): Define partial specializations for std::allocator. (__use_future_ch): Overload constructor for completion tokens using diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index 1a3eb88..2559c57 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -63,23 +63,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ -#if __cplusplus <= 201703L /// allocator<void> specialization. template<> class allocator<void> { public: + typedef void value_type; typedef size_t size_type; typedef ptrdiff_t difference_type; +#if __cplusplus <= 201703L typedef void* pointer; typedef const void* const_pointer; - typedef void value_type; template<typename _Tp1> struct rebind { typedef allocator<_Tp1> other; }; +#else + allocator() = default; -#if __cplusplus >= 201103L + template<typename _Up> + constexpr + allocator(const allocator<_Up>&) { } +#endif // ! C++20 + +#if __cplusplus >= 201103L && __cplusplus <= 201703L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef true_type propagate_on_container_move_assignment; @@ -98,9 +105,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION destroy(_Up* __p) noexcept(noexcept(__p->~_Up())) { __p->~_Up(); } -#endif // C++11 +#endif // C++11 to C++17 }; -#endif // ! C++20 /** * @brief The @a standard allocator, as per [20.4]. @@ -154,9 +160,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { } -#if __cplusplus <= 201703L + _GLIBCXX20_CONSTEXPR ~allocator() _GLIBCXX_NOTHROW { } -#endif #if __cplusplus > 201703L [[nodiscard,__gnu__::__always_inline__]] diff --git a/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc b/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc index 968e1de..dd7cd67 100644 --- a/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc +++ b/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc @@ -23,6 +23,9 @@ template<typename T> struct Alloc : std::allocator<T> { }; using T = std::allocator_traits<Alloc<int>>; - // Prior to C++20 this finds std::allocator<int>::rebind and so fails: static_assert( std::is_same_v<T::rebind_alloc<long>, Alloc<long>> ); + +using V = std::allocator_traits<Alloc<void>>; +// Prior to C++20 this finds std::allocator<void>::rebind and so fails: +static_assert( std::is_same_v<V::rebind_alloc<long>, Alloc<long>> ); diff --git a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc index e986cc9..ef193fb 100644 --- a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc +++ b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc @@ -54,3 +54,14 @@ static_assert( !has_rebind<A> ); static_assert( !has_construct<A> ); static_assert( !has_destroy<A> ); static_assert( !has_max_size<A> ); + +using V = std::allocator<void>; + +static_assert( !has_pointer<V> ); +static_assert( !has_const_pointer<V> ); +static_assert( !has_reference<V> ); +static_assert( !has_const_reference<V> ); +static_assert( !has_rebind<V> ); +static_assert( !has_construct<V> ); +static_assert( !has_destroy<V> ); +static_assert( !has_max_size<V> ); diff --git a/libstdc++-v3/testsuite/20_util/allocator/void.cc b/libstdc++-v3/testsuite/20_util/allocator/void.cc index d7aa6bd..9d94fac 100644 --- a/libstdc++-v3/testsuite/20_util/allocator/void.cc +++ b/libstdc++-v3/testsuite/20_util/allocator/void.cc @@ -33,6 +33,28 @@ test01() std::allocator_traits<alloc_type>::destroy(a, &i); } +// These properties are formally unspecified, but have always been true for +// the libstdc++ definition of allocator<void>. +static_assert( + std::is_trivially_default_constructible<std::allocator<void>>::value, + "explicit specialization has trivial default constructor"); +static_assert( + std::is_trivially_copy_constructible<std::allocator<void>>::value, + "explicit specialization has trivial copy constructor"); +static_assert( + std::is_trivially_move_constructible<std::allocator<void>>::value, + "explicit specialization has trivial move constructor"); +static_assert( + std::is_trivially_destructible<std::allocator<void>>::value, + "explicit specialization has trivial destructor"); + +#if __cplusplus > 201703L +// C++20 removes the allocator<void> explicit specialization, so it can now be +// constructed using the converting constructor from other specializations. +static_assert( std::is_constructible_v<std::allocator<void>, + std::allocator<int>> ); +#endif + int main() { diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc index b786fae..f122768 100644 --- a/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc +++ b/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc @@ -1,4 +1,4 @@ -// { dg-do run { target { { c++11_only || c++14_only } || c++17_only } } } +// { dg-do run { target { c++11 && { ! c++2a } } } } // 2007-10-26 Paolo Carlini <pcarlini@suse.de> diff --git a/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc b/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc index 5b23e5b..cfe93a7 100644 --- a/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc +++ b/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc @@ -1,4 +1,4 @@ -// { dg-do run { target { { c++11_only || c++14_only } || c++17_only } } } +// { dg-do run { target { c++11 && { ! c++2a } } } } // 2007-10-26 Paolo Carlini <pcarlini@suse.de> |