aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-10-24 15:29:41 +0000
committerJonathan Wakely <jwakely@redhat.com>2019-10-24 15:29:41 +0000
commit007fd47047b02f685f07bac58d6a81462dae0a76 (patch)
tree7118ea8e1c16b8855187cdfe10af00f75cff4891
parent58946cdecdd60c547b3515f2c202c85960f0ed63 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@277410 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog13
-rw-r--r--libstdc++-v3/include/bits/allocator.h19
-rw-r--r--libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc5
-rw-r--r--libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc11
-rw-r--r--libstdc++-v3/testsuite/20_util/allocator/void.cc22
-rw-r--r--libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc2
7 files changed, 64 insertions, 10 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 13e834bfb3e..0ae347ee4ff 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 1a3eb88eded..2559c57b12e 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 968e1de931b..dd7cd67f943 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 e986cc9a809..ef193fb1bf1 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 d7aa6bd80ed..9d94fac3cc0 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 b786fae9f0a..f122768d8ac 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 5b23e5b4a2c..cfe93a7b6d9 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>