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
This commit is contained in:
parent
bf037872d3
commit
75c6a925da
|
@ -1,5 +1,18 @@
|
||||||
2019-10-24 Jonathan Wakely <jwakely@redhat.com>
|
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):
|
* include/experimental/executor (__use_future_ct, use_future_t):
|
||||||
Define partial specializations for std::allocator.
|
Define partial specializations for std::allocator.
|
||||||
(__use_future_ch): Overload constructor for completion tokens using
|
(__use_future_ch): Overload constructor for completion tokens using
|
||||||
|
|
|
@ -63,23 +63,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if __cplusplus <= 201703L
|
|
||||||
/// allocator<void> specialization.
|
/// allocator<void> specialization.
|
||||||
template<>
|
template<>
|
||||||
class allocator<void>
|
class allocator<void>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef void value_type;
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
|
#if __cplusplus <= 201703L
|
||||||
typedef void* pointer;
|
typedef void* pointer;
|
||||||
typedef const void* const_pointer;
|
typedef const void* const_pointer;
|
||||||
typedef void value_type;
|
|
||||||
|
|
||||||
template<typename _Tp1>
|
template<typename _Tp1>
|
||||||
struct rebind
|
struct rebind
|
||||||
{ typedef allocator<_Tp1> other; };
|
{ 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
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||||
// 2103. std::allocator propagate_on_container_move_assignment
|
// 2103. std::allocator propagate_on_container_move_assignment
|
||||||
typedef true_type propagate_on_container_move_assignment;
|
typedef true_type propagate_on_container_move_assignment;
|
||||||
|
@ -98,9 +105,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
destroy(_Up* __p)
|
destroy(_Up* __p)
|
||||||
noexcept(noexcept(__p->~_Up()))
|
noexcept(noexcept(__p->~_Up()))
|
||||||
{ __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].
|
* @brief The @a standard allocator, as per [20.4].
|
||||||
|
@ -154,9 +160,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_GLIBCXX20_CONSTEXPR
|
_GLIBCXX20_CONSTEXPR
|
||||||
allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
|
allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
|
||||||
|
|
||||||
#if __cplusplus <= 201703L
|
_GLIBCXX20_CONSTEXPR
|
||||||
~allocator() _GLIBCXX_NOTHROW { }
|
~allocator() _GLIBCXX_NOTHROW { }
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __cplusplus > 201703L
|
#if __cplusplus > 201703L
|
||||||
[[nodiscard,__gnu__::__always_inline__]]
|
[[nodiscard,__gnu__::__always_inline__]]
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
template<typename T> struct Alloc : std::allocator<T> { };
|
template<typename T> struct Alloc : std::allocator<T> { };
|
||||||
|
|
||||||
using T = std::allocator_traits<Alloc<int>>;
|
using T = std::allocator_traits<Alloc<int>>;
|
||||||
|
|
||||||
// Prior to C++20 this finds std::allocator<int>::rebind and so fails:
|
// 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>> );
|
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>> );
|
||||||
|
|
|
@ -54,3 +54,14 @@ static_assert( !has_rebind<A> );
|
||||||
static_assert( !has_construct<A> );
|
static_assert( !has_construct<A> );
|
||||||
static_assert( !has_destroy<A> );
|
static_assert( !has_destroy<A> );
|
||||||
static_assert( !has_max_size<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> );
|
||||||
|
|
|
@ -33,6 +33,28 @@ test01()
|
||||||
std::allocator_traits<alloc_type>::destroy(a, &i);
|
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
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
// 2007-10-26 Paolo Carlini <pcarlini@suse.de>
|
||||||
|
|
||||||
|
|
|
@ -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>
|
// 2007-10-26 Paolo Carlini <pcarlini@suse.de>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue