public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Remove redundant std::allocator members for C++20
@ 2019-10-22 21:40 Jonathan Wakely
  2019-10-22 22:09 ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2019-10-22 21:40 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 390 bytes --]

C++20 removes a number of std::allocator members that have correct
defaults provided by std::allocator_traits, so aren't needed.

Several extensions including __gnu_cxx::hash_map and tr1 containers are
no longer usable with std::allocator in C++20 mode. They need to be
updated to use __gnu_cxx::__alloc_traits in a follow-up patch.

Tested powerpc64le-linux, committed to trunk.


[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 45223 bytes --]

commit cdf9061153ca8da988f9131de32ce3a1b25a94a9
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Oct 22 19:59:55 2019 +0100

    Remove redundant std::allocator members for C++20
    
    C++20 removes a number of std::allocator members that have correct
    defaults provided by std::allocator_traits, so aren't needed.
    
    Several extensions including __gnu_cxx::hash_map and tr1 containers are
    no longer usable with std::allocator in C++20 mode. They need to be
    updated to use __gnu_cxx::__alloc_traits in a follow-up patch.
    
            * include/bits/alloc_traits.h
            (allocator_traits<allocator<T>>::allocate): Ignore hint for C++20.
            (allocator_traits<allocator<T>>::construct): Perform placement new
            directly for C++20, instead of calling allocator<T>::construct.
            (allocator_traits<allocator<T>>::destroy): Call destructor directly
            for C++20, instead of calling allocator<T>::destroy.
            (allocator_traits<allocator<T>>::max_size): Return value directly
            for C++20, instead of calling std::allocator<T>::max_size().
            (__do_alloc_on_copy, __do_alloc_on_move, __do_alloc_on_swap): Do not
            define for C++17 and up.
            (__alloc_on_copy, __alloc_on_move, __alloc_on_swap): Use if-constexpr
            for C++17 and up, instead of tag dispatching.
            * include/bits/allocator.h (allocator<void>): Remove for C++20.
            (allocator::pointer, allocator::const_pointer, allocator::reference)
            (allocator::const_reference, allocator::rebind): Remove for C++20.
            * include/bits/basic_string.h (basic_string): Use __alloc_traits to
            rebind allocator.
            * include/bits/memoryfwd.h (allocator<void>): Remove for C++20.
            * include/ext/debug_allocator.h: Use __alloc_traits for rebinding.
            * include/ext/malloc_allocator.h (malloc_allocator::~malloc_allocator)
            (malloc_allocator::pointer, malloc_allocator::const_pointer)
            (malloc_allocator::reference, malloc_allocator::const_reference)
            (malloc_allocator::rebind, malloc_allocator::max_size)
            (malloc_allocator::construct, malloc_allocator::destroy): Do not
            define for C++20.
            (malloc_allocator::_M_max_size): Define new function.
            * include/ext/new_allocator.h (new_allocator::~new_allocator)
            (new_allocator::pointer, new_allocator::const_pointer)
            (new_allocator::reference, new_allocator::const_reference)
            (new_allocator::rebind, new_allocator::max_size)
            (new_allocator::construct, new_allocator::destroy): Do not
            define for C++20.
            (new_allocator::_M_max_size): Define new function.
            * include/ext/rc_string_base.h (__rc_string_base::_Rep): Use
            __alloc_traits to rebind allocator.
            * include/ext/rope (_Rope_rep_base, _Rope_base): Likewise.
            (rope::rope(CharT, const allocator_type&)): Use __alloc_traits
            to construct character.
            * include/ext/slist (_Slist_base): Use __alloc_traits to rebind
            allocator.
            * include/ext/sso_string_base.h (__sso_string_base::_M_max_size):
            Use __alloc_traits.
            * include/ext/throw_allocator.h (throw_allocator): Do not use optional
            members of std::allocator, use __alloc_traits members instead.
            * include/ext/vstring.h (__versa_string): Use __alloc_traits.
            * include/ext/vstring_util.h (__vstring_utility): Likewise.
            * include/std/memory: Include <bits/alloc_traits.h>.
            * testsuite/20_util/allocator/8230.cc: Use __gnu_test::max_size.
            * testsuite/20_util/allocator/rebind_c++20.cc: New test.
            * testsuite/20_util/allocator/requirements/typedefs.cc: Do not check
            for pointer, const_pointer, reference, const_reference or rebind in
            C++20.
            * testsuite/20_util/allocator/requirements/typedefs_c++20.cc: New test.
            * testsuite/23_containers/deque/capacity/29134.cc: Use
            __gnu_test::max_size.
            * testsuite/23_containers/forward_list/capacity/1.cc: Likewise.
            * testsuite/23_containers/list/capacity/29134.cc: Likewise.
            * testsuite/23_containers/map/capacity/29134.cc: Likewise.
            * testsuite/23_containers/multimap/capacity/29134.cc: Likewise.
            * testsuite/23_containers/multiset/capacity/29134.cc: Likewise.
            * testsuite/23_containers/set/capacity/29134.cc: Likewise.
            * testsuite/23_containers/vector/capacity/29134.cc: Likewise.
            * testsuite/ext/malloc_allocator/variadic_construct.cc: Do not run
            test for C++20.
            * testsuite/ext/new_allocator/variadic_construct.cc: Likewise.
            * testsuite/ext/vstring/capacity/29134.cc: Use __gnu_test::max_size.
            * testsuite/util/replacement_memory_operators.h: Do not assume
            Alloc::pointer exists.
            * testsuite/util/testsuite_allocator.h (__gnu_test::max_size): Define
            helper to call max_size for any allocator.

diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index cda768bf391..62bbf0b2e31 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -393,6 +393,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       /// The allocator type
       using allocator_type = allocator<_Tp>;
+
       /// The allocated type
       using value_type = _Tp;
 
@@ -455,7 +456,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       _GLIBCXX_NODISCARD static pointer
       allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
-      { return __a.allocate(__n, __hint); }
+      {
+#if __cplusplus <= 201703L
+	return __a.allocate(__n, __hint);
+#else
+	return __a.allocate(__n);
+#endif
+      }
 
       /**
        *  @brief  Deallocate memory.
@@ -480,8 +487,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up, typename... _Args>
 	static void
 	construct(allocator_type& __a, _Up* __p, _Args&&... __args)
-	noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
-	{ __a.construct(__p, std::forward<_Args>(__args)...); }
+	noexcept(noexcept(::new((void*)__p) _Up(std::forward<_Args>(__args)...)))
+	{
+#if __cplusplus <= 201703L
+	  __a.construct(__p, std::forward<_Args>(__args)...);
+#else
+	  ::new((void*)__p) _Up(std::forward<_Args>(__args)...);
+#endif
+	}
 
       /**
        *  @brief  Destroy an object of type @a _Up
@@ -493,8 +506,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up>
 	static void
 	destroy(allocator_type& __a, _Up* __p)
-	noexcept(noexcept(__a.destroy(__p)))
-	{ __a.destroy(__p); }
+	noexcept(is_nothrow_destructible<_Up>::value)
+	{
+#if __cplusplus <= 201703L
+	  __a.destroy(__p);
+#else
+	  __p->~_Up();
+#endif
+	}
 
       /**
        *  @brief  The maximum supported allocation size
@@ -503,7 +522,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       static size_type
       max_size(const allocator_type& __a) noexcept
-      { return __a.max_size(); }
+      {
+#if __cplusplus <= 201703L
+	return __a.max_size();
+#else
+	return size_t(-1) / sizeof(value_type);
+#endif
+      }
 
       /**
        *  @brief  Obtain an allocator to use when copying a container.
@@ -515,7 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return __rhs; }
     };
 
-
+#if __cplusplus < 201703L
   template<typename _Alloc>
     inline void
     __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
@@ -525,13 +550,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline void
     __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
     { }
+#endif
 
   template<typename _Alloc>
     inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
     {
       typedef allocator_traits<_Alloc> __traits;
       typedef typename __traits::propagate_on_container_copy_assignment __pocca;
+#if __cplusplus >= 201703L
+      if constexpr (__pocca::value)
+	__one = __two;
+#else
       __do_alloc_on_copy(__one, __two, __pocca());
+#endif
     }
 
   template<typename _Alloc>
@@ -541,6 +572,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __traits::select_on_container_copy_construction(__a);
     }
 
+#if __cplusplus < 201703L
   template<typename _Alloc>
     inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
     { __one = std::move(__two); }
@@ -548,15 +580,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Alloc>
     inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
     { }
+#endif
 
   template<typename _Alloc>
     inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
     {
       typedef allocator_traits<_Alloc> __traits;
       typedef typename __traits::propagate_on_container_move_assignment __pocma;
+#if __cplusplus >= 201703L
+      if constexpr (__pocma::value)
+	__one = std::move(__two);
+#else
       __do_alloc_on_move(__one, __two, __pocma());
+#endif
     }
 
+#if __cplusplus < 201703L
   template<typename _Alloc>
     inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
     {
@@ -567,13 +606,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Alloc>
     inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
     { }
+#endif
 
   template<typename _Alloc>
     inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
     {
       typedef allocator_traits<_Alloc> __traits;
       typedef typename __traits::propagate_on_container_swap __pocs;
+#if __cplusplus >= 201703L
+      if constexpr (__pocs::value)
+	{
+	  using std::swap;
+	  swap(__one, __two);
+	}
+#else
       __do_alloc_on_swap(__one, __two, __pocs());
+#endif
     }
 
   template<typename _Alloc, typename _Tp,
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
index f0f8fe41e31..62a40a17e3c 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -63,6 +63,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *  @{
    */
 
+#if __cplusplus <= 201703L
   /// allocator<void> specialization.
   template<>
     class allocator<void>
@@ -97,8 +98,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	destroy(_Up* __p)
 	noexcept(noexcept(__p->~_Up()))
 	{ __p->~_Up(); }
-#endif
+#endif // C++11
     };
+#endif // ! C++20
 
   /**
    * @brief  The @a standard allocator, as per [20.4].
@@ -111,18 +113,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     class allocator : public __allocator_base<_Tp>
     {
-   public:
+    public:
+      typedef _Tp        value_type;
       typedef size_t     size_type;
       typedef ptrdiff_t  difference_type;
+#if __cplusplus <= 201703L
       typedef _Tp*       pointer;
       typedef const _Tp* const_pointer;
       typedef _Tp&       reference;
       typedef const _Tp& const_reference;
-      typedef _Tp        value_type;
 
       template<typename _Tp1>
 	struct rebind
 	{ typedef allocator<_Tp1> other; };
+#endif
 
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index f1bdc6c553f..37e75b455d3 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3138,7 +3138,9 @@ _GLIBCXX_END_NAMESPACE_CXX11
   template<typename _CharT, typename _Traits, typename _Alloc>
     class basic_string
     {
-      typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<_CharT>::other _CharT_alloc_type;
+      typedef __gnu_cxx::__alloc_traits<_CharT_alloc_type> _CharT_alloc_traits;
 
       // Types:
     public:
@@ -3154,8 +3156,8 @@ _GLIBCXX_END_NAMESPACE_CXX11
       typedef value_type&				    reference;
       typedef const value_type&				    const_reference;
 #endif
-      typedef typename _CharT_alloc_type::pointer	    pointer;
-      typedef typename _CharT_alloc_type::const_pointer	    const_pointer;
+      typedef typename _CharT_alloc_traits::pointer	    pointer;
+      typedef typename _CharT_alloc_traits::const_pointer   const_pointer;
       typedef __gnu_cxx::__normal_iterator<pointer, basic_string>  iterator;
       typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
                                                             const_iterator;
@@ -3191,7 +3193,8 @@ _GLIBCXX_END_NAMESPACE_CXX11
       struct _Rep : _Rep_base
       {
 	// Types:
-	typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
+	typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	  rebind<char>::other _Raw_bytes_alloc;
 
 	// (Public) Data members:
 
diff --git a/libstdc++-v3/include/bits/memoryfwd.h b/libstdc++-v3/include/bits/memoryfwd.h
index 8b1664a398d..d42eabeceb8 100644
--- a/libstdc++-v3/include/bits/memoryfwd.h
+++ b/libstdc++-v3/include/bits/memoryfwd.h
@@ -63,8 +63,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename>
     class allocator;
 
+#if __cplusplus <= 201703L
   template<>
     class allocator<void>;
+#endif
 
   /// Declare uses_allocator so it can be specialized in \<queue\> etc.
   template<typename, typename>
diff --git a/libstdc++-v3/include/ext/debug_allocator.h b/libstdc++-v3/include/ext/debug_allocator.h
index 08f0eb23f5b..b8e0e64d7bd 100644
--- a/libstdc++-v3/include/ext/debug_allocator.h
+++ b/libstdc++-v3/include/ext/debug_allocator.h
@@ -89,7 +89,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Alloc			_M_allocator;
 
       template<typename _Alloc2,
-	       typename = typename _Alloc2::template rebind<value_type>::other>
+	       typename = typename __alloc_traits<_Alloc2>::template
+			   rebind<value_type>::other>
 	struct __convertible
 	{ };
 
diff --git a/libstdc++-v3/include/ext/malloc_allocator.h b/libstdc++-v3/include/ext/malloc_allocator.h
index 1bc76372f44..cf6284080e8 100644
--- a/libstdc++-v3/include/ext/malloc_allocator.h
+++ b/libstdc++-v3/include/ext/malloc_allocator.h
@@ -54,17 +54,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     class malloc_allocator
     {
     public:
+      typedef _Tp        value_type;
       typedef std::size_t     size_type;
       typedef std::ptrdiff_t  difference_type;
+#if __cplusplus <= 201703L
       typedef _Tp*       pointer;
       typedef const _Tp* const_pointer;
       typedef _Tp&       reference;
       typedef const _Tp& const_reference;
-      typedef _Tp        value_type;
 
       template<typename _Tp1>
         struct rebind
         { typedef malloc_allocator<_Tp1> other; };
+#endif
 
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -83,6 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         malloc_allocator(const malloc_allocator<_Tp1>&)
 	_GLIBCXX_USE_NOEXCEPT { }
 
+#if __cplusplus <= 201703L
       ~malloc_allocator() _GLIBCXX_USE_NOEXCEPT { }
 
       pointer
@@ -92,16 +95,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const_pointer
       address(const_reference __x) const _GLIBCXX_NOEXCEPT
       { return std::__addressof(__x); }
+#endif
 
       // NB: __n is permitted to be 0.  The C++ standard says nothing
       // about what the return value is when __n == 0.
-      pointer
+      _Tp*
       allocate(size_type __n, const void* = 0)
       {
-	if (__n > this->max_size())
+	if (__n > this->_M_max_size())
 	  std::__throw_bad_alloc();
 
-	pointer __ret = 0;
+	_Tp* __ret = 0;
 #if __cpp_aligned_new
 #if __cplusplus > 201402L && _GLIBCXX_HAVE_ALIGNED_ALLOC
 	if (alignof(_Tp) > alignof(std::max_align_t))
@@ -131,18 +135,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // __p is not permitted to be a null pointer.
       void
-      deallocate(pointer __p, size_type)
+      deallocate(_Tp* __p, size_type)
       { std::free(static_cast<void*>(__p)); }
 
+#if __cplusplus <= 201703L
       size_type
       max_size() const _GLIBCXX_USE_NOEXCEPT 
-      {
-#if __PTRDIFF_MAX__ < __SIZE_MAX__
-	return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
-#else
-	return std::size_t(-1) / sizeof(_Tp);
-#endif
-      }
+      { return _M_max_size(); }
 
 #if __cplusplus >= 201103L
       template<typename _Up, typename... _Args>
@@ -160,13 +159,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 402. wrong new expression in [some_] allocator::construct
-      void 
-      construct(pointer __p, const _Tp& __val) 
+      void
+      construct(pointer __p, const _Tp& __val)
       { ::new((void *)__p) value_type(__val); }
 
-      void 
+      void
       destroy(pointer __p) { __p->~_Tp(); }
 #endif
+#endif // ! C++20
 
       template<typename _Up>
 	friend bool
@@ -179,6 +179,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	operator!=(const malloc_allocator&, const malloc_allocator<_Up>&)
 	_GLIBCXX_NOTHROW
 	{ return false; }
+
+    private:
+      _GLIBCXX_CONSTEXPR size_type
+      _M_max_size() const _GLIBCXX_USE_NOEXCEPT
+      {
+#if __PTRDIFF_MAX__ < __SIZE_MAX__
+	return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
+#else
+	return std::size_t(-1) / sizeof(_Tp);
+#endif
+      }
     };
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/ext/new_allocator.h b/libstdc++-v3/include/ext/new_allocator.h
index ee699532c6a..cff9f1dca9c 100644
--- a/libstdc++-v3/include/ext/new_allocator.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -55,17 +55,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     class new_allocator
     {
     public:
+      typedef _Tp        value_type;
       typedef std::size_t     size_type;
       typedef std::ptrdiff_t  difference_type;
+#if __cplusplus <= 201703L
       typedef _Tp*       pointer;
       typedef const _Tp* const_pointer;
       typedef _Tp&       reference;
       typedef const _Tp& const_reference;
-      typedef _Tp        value_type;
 
       template<typename _Tp1>
 	struct rebind
 	{ typedef new_allocator<_Tp1> other; };
+#endif
 
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -83,6 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_GLIBCXX20_CONSTEXPR
 	new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
 
+#if __cplusplus <= 201703L
       ~new_allocator() _GLIBCXX_USE_NOEXCEPT { }
 
       pointer
@@ -92,13 +95,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const_pointer
       address(const_reference __x) const _GLIBCXX_NOEXCEPT
       { return std::__addressof(__x); }
+#endif
 
       // NB: __n is permitted to be 0.  The C++ standard says nothing
       // about what the return value is when __n == 0.
-      _GLIBCXX_NODISCARD pointer
+      _GLIBCXX_NODISCARD _Tp*
       allocate(size_type __n, const void* = static_cast<const void*>(0))
       {
-	if (__n > this->max_size())
+	if (__n > this->_M_max_size())
 	  std::__throw_bad_alloc();
 
 #if __cpp_aligned_new
@@ -113,7 +117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // __p is not permitted to be a null pointer.
       void
-      deallocate(pointer __p, size_type __t)
+      deallocate(_Tp* __p, size_type __t)
       {
 #if __cpp_aligned_new
 	if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
@@ -133,15 +137,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 			 );
       }
 
+#if __cplusplus <= 201703L
       size_type
       max_size() const _GLIBCXX_USE_NOEXCEPT
-      {
-#if __PTRDIFF_MAX__ < __SIZE_MAX__
-	return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
-#else
-	return std::size_t(-1) / sizeof(_Tp);
-#endif
-      }
+      { return _M_max_size(); }
 
 #if __cplusplus >= 201103L
       template<typename _Up, typename... _Args>
@@ -166,6 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void
       destroy(pointer __p) { __p->~_Tp(); }
 #endif
+#endif // ! C++20
 
       template<typename _Up>
 	friend bool
@@ -178,6 +178,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	operator!=(const new_allocator&, const new_allocator<_Up>&)
 	_GLIBCXX_NOTHROW
 	{ return false; }
+
+    private:
+      _GLIBCXX_CONSTEXPR size_type
+      _M_max_size() const _GLIBCXX_USE_NOEXCEPT
+      {
+#if __PTRDIFF_MAX__ < __SIZE_MAX__
+	return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
+#else
+	return std::size_t(-1) / sizeof(_Tp);
+#endif
+      }
     };
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/ext/rc_string_base.h b/libstdc++-v3/include/ext/rc_string_base.h
index 529035c5f61..2cf5fb0c5e3 100644
--- a/libstdc++-v3/include/ext/rc_string_base.h
+++ b/libstdc++-v3/include/ext/rc_string_base.h
@@ -31,6 +31,7 @@
 #define _RC_STRING_BASE_H 1
 
 #include <ext/atomicity.h>
+#include <ext/alloc_traits.h>
 #include <bits/stl_iterator_base_funcs.h>
 
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
@@ -120,7 +121,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  _CharT            _M_align;
 	};
 
-	typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type;
+	typedef typename __alloc_traits<_Alloc>::template rebind<_Rep>::other
+	  _Rep_alloc_type;
 
  	_CharT*
 	_M_refdata() throw()
diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope
index 0788dee3c71..bfb29e1852d 100644
--- a/libstdc++-v3/include/ext/rope
+++ b/libstdc++-v3/include/ext/rope
@@ -53,6 +53,7 @@
 #include <bits/stl_numeric.h>
 #include <bits/allocator.h>
 #include <bits/gthr.h>
+#include <ext/alloc_traits.h>
 #include <tr1/functional>
 
 # ifdef __GC
@@ -565,7 +566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 # define __ROPE_DEFINE_ALLOC(_Tp, __name) \
         typedef typename \
-          _Alloc::template rebind<_Tp>::other __name##Alloc; \
+          __alloc_traits<_Alloc>::template rebind<_Tp>::other __name##Alloc; \
         static _Tp* __name##_allocate(size_type __n) \
           { return __name##Alloc().allocate(__n); } \
         static void __name##_deallocate(_Tp *__p, size_type __n) \
@@ -1499,7 +1500,7 @@ protected:
 
 #define __ROPE_DEFINE_ALLOC(_Tp, __name) \
         typedef typename \
-          _Alloc::template rebind<_Tp>::other __name##Alloc; \
+          __alloc_traits<_Alloc>::template rebind<_Tp>::other __name##Alloc; \
         static _Tp* __name##_allocate(std::size_t __n) \
           { return __name##Alloc().allocate(__n); } \
         static void __name##_deallocate(_Tp *__p, std::size_t __n) \
@@ -1855,7 +1856,8 @@ protected:
       {
 	_CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1));
 	
-	_M_get_allocator().construct(__buf, __c);
+	__alloc_traits<allocator_type>::construct(_M_get_allocator(),
+						  __buf, __c);
 	__try
 	  {
 	    this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1,
diff --git a/libstdc++-v3/include/ext/slist b/libstdc++-v3/include/ext/slist
index ff2ea150c4a..93522caf1f6 100644
--- a/libstdc++-v3/include/ext/slist
+++ b/libstdc++-v3/include/ext/slist
@@ -217,10 +217,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template <class _Tp, class _Alloc>
     struct _Slist_base
-    : public _Alloc::template rebind<_Slist_node<_Tp> >::other
+    : public __alloc_traits<_Alloc>::template rebind<_Slist_node<_Tp> >::other
     {
-      typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other
-        _Node_alloc;
+      typedef typename __alloc_traits<_Alloc>::template
+	rebind<_Slist_node<_Tp> >::other _Node_alloc;
       typedef _Alloc allocator_type;
 
       allocator_type
diff --git a/libstdc++-v3/include/ext/sso_string_base.h b/libstdc++-v3/include/ext/sso_string_base.h
index beae593efa0..e86d81011dd 100644
--- a/libstdc++-v3/include/ext/sso_string_base.h
+++ b/libstdc++-v3/include/ext/sso_string_base.h
@@ -140,7 +140,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       size_type
       _M_max_size() const
-      { return (_M_get_allocator().max_size() - 1) / 2; }
+      {
+	typedef __alloc_traits<_CharT_alloc_type> _ATraits;
+	return (_ATraits::max_size(_M_get_allocator()) - 1) / 2;
+      }
 
       _CharT*
       _M_data() const
diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h
index 38e80f721da..f5da751eb69 100644
--- a/libstdc++-v3/include/ext/throw_allocator.h
+++ b/libstdc++-v3/include/ext/throw_allocator.h
@@ -62,6 +62,7 @@
 # include <tr1/functional>
 # include <tr1/random>
 #endif
+#include <ext/alloc_traits.h>
 
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
@@ -814,12 +815,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       std::allocator<value_type> 		_M_allocator;
 
+      typedef __gnu_cxx::__alloc_traits<std::allocator<value_type> > traits;
+
       using condition_type::throw_conditionally;
 
     public:
       size_type
       max_size() const _GLIBCXX_USE_NOEXCEPT
-      { return _M_allocator.max_size(); }
+      { return traits::max_size(_M_allocator); }
 
       pointer
       address(reference __x) const _GLIBCXX_NOEXCEPT
@@ -830,13 +833,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return std::__addressof(__x); }
 
       _GLIBCXX_NODISCARD pointer
-      allocate(size_type __n, std::allocator<void>::const_pointer hint = 0)
+      allocate(size_type __n, const void* hint = 0)
       {
 	if (__n > this->max_size())
 	  std::__throw_bad_alloc();
 
 	throw_conditionally();
-	pointer const a = _M_allocator.allocate(__n, hint);
+	pointer const a = traits::allocate(_M_allocator, __n, hint);
 	insert(a, sizeof(value_type) * __n);
 	return a;
       }
@@ -846,7 +849,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         void
         construct(_Up* __p, _Args&&... __args)
 	{
-	  _M_allocator.construct(__p, std::forward<_Args>(__args)...);
+	  traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...);
 	  insert_construct(__p);
 	}
 
@@ -855,7 +858,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         destroy(_Up* __p)
         {
 	  erase_construct(__p);
-	  _M_allocator.destroy(__p);
+	  traits::destroy(_M_allocator, __p);
 	}
 #else
       void
diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h
index 5942218531f..23ccf15de5b 100644
--- a/libstdc++-v3/include/ext/vstring.h
+++ b/libstdc++-v3/include/ext/vstring.h
@@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       typedef _Base<_CharT, _Traits, _Alloc>                __vstring_base;    
       typedef typename __vstring_base::_CharT_alloc_type    _CharT_alloc_type;
+      typedef __alloc_traits<_CharT_alloc_type> _CharT_alloc_traits;
 
       // Types:
     public:
@@ -68,8 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef typename _CharT_alloc_type::difference_type   difference_type;
       typedef value_type&               	            reference;
       typedef const value_type&                             const_reference;
-      typedef typename _CharT_alloc_type::pointer	    pointer;
-      typedef typename _CharT_alloc_type::const_pointer	    const_pointer;
+      typedef typename _CharT_alloc_traits::pointer	    pointer;
+      typedef typename _CharT_alloc_traits::const_pointer   const_pointer;
       typedef __gnu_cxx::__normal_iterator<pointer, __versa_string>  iterator;
       typedef __gnu_cxx::__normal_iterator<const_pointer, __versa_string>
                                                             const_iterator;
diff --git a/libstdc++-v3/include/ext/vstring_util.h b/libstdc++-v3/include/ext/vstring_util.h
index 5d00b165cbe..f539a6b0f2c 100644
--- a/libstdc++-v3/include/ext/vstring_util.h
+++ b/libstdc++-v3/include/ext/vstring_util.h
@@ -40,6 +40,7 @@
 #include <bits/ostream_insert.h>
 #include <bits/stl_iterator.h>
 #include <ext/numeric_traits.h>
+#include <ext/alloc_traits.h>
 #include <bits/move.h>
 #include <bits/range_access.h>
 
@@ -50,14 +51,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _CharT, typename _Traits, typename _Alloc>
     struct __vstring_utility
     {
-      typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
+      typedef typename __alloc_traits<_Alloc>::template rebind<_CharT>::other
+	_CharT_alloc_type;
+      typedef __alloc_traits<_CharT_alloc_type> _CharT_alloc_traits;
 
       typedef _Traits					    traits_type;
       typedef typename _Traits::char_type		    value_type;
       typedef typename _CharT_alloc_type::size_type	    size_type;
       typedef typename _CharT_alloc_type::difference_type   difference_type;
-      typedef typename _CharT_alloc_type::pointer	    pointer;
-      typedef typename _CharT_alloc_type::const_pointer	    const_pointer;
+      typedef typename _CharT_alloc_traits::pointer	    pointer;
+      typedef typename _CharT_alloc_traits::const_pointer   const_pointer;
 
       // For __sso_string.
       typedef __gnu_cxx::
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 0a483d2d8d1..4f09b8deb2c 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -76,6 +76,7 @@
 #  include <bits/functexcept.h>
 #  include <bits/stl_function.h>  // std::less
 #  include <bits/uses_allocator.h>
+#  include <bits/alloc_traits.h>
 #  include <type_traits>
 #  include <debug/debug.h>
 #  include <bits/unique_ptr.h>
diff --git a/libstdc++-v3/testsuite/20_util/allocator/8230.cc b/libstdc++-v3/testsuite/20_util/allocator/8230.cc
index 917e64de374..2559a5117fb 100644
--- a/libstdc++-v3/testsuite/20_util/allocator/8230.cc
+++ b/libstdc++-v3/testsuite/20_util/allocator/8230.cc
@@ -22,6 +22,7 @@
 #include <memory>
 #include <stdexcept>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/8230
 void test02()
@@ -30,11 +31,11 @@ void test02()
   try 
     {
       std::allocator<int> alloc;
-      const std::allocator<int>::size_type n = alloc.max_size();
+      const std::allocator<int>::size_type n = __gnu_test::max_size(alloc);
       int* p = alloc.allocate(n + 1);
       p[n] = 2002;
     } 
-  catch(const std::bad_alloc& e) 
+  catch(const std::bad_alloc& e)
     {
       // Allowed.
       test = true;
diff --git a/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc b/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc
new file mode 100644
index 00000000000..968e1de931b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <memory>
+
+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>> );
diff --git a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc
index d293e6b06b6..3275164f144 100644
--- a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc
+++ b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs.cc
@@ -30,6 +30,7 @@ static_assert( is_same<allocator<int>::size_type, std::size_t>::value,
                "size_type" );
 static_assert( is_same<allocator<int>::difference_type, std::ptrdiff_t>::value,
                "difference_type" );
+#if __cplusplus <= 201703L
 static_assert( is_same<allocator<int>::pointer, int*>::value,
                "pointer" );
 static_assert( is_same<allocator<int>::const_pointer, const int*>::value,
@@ -38,12 +39,15 @@ static_assert( is_same<allocator<int>::reference, int&>::value,
                "reference" );
 static_assert( is_same<allocator<int>::const_reference, const int&>::value,
                "const_reference" );
+#endif
 static_assert( is_same<allocator<int>::value_type, int>::value,
                "value_type" );
 
+#if __cplusplus <= 201703L
 static_assert( is_same<allocator<int>::rebind<char>::other,
                        allocator<char>>::value,
                "rebind::other" );
+#endif
 
 static_assert( is_same<allocator<int>::propagate_on_container_move_assignment,
                        std::true_type>::value,
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
new file mode 100644
index 00000000000..e986cc9a809
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <memory>
+
+template<typename Alloc>
+  concept has_pointer = requires { typename Alloc::pointer; };
+
+template<typename Alloc>
+  concept has_const_pointer = requires { typename Alloc::const_pointer; };
+
+template<typename Alloc>
+  concept has_reference = requires { typename Alloc::reference; };
+
+template<typename Alloc>
+  concept has_const_reference = requires { typename Alloc::const_reference; };
+
+template<typename Alloc>
+  concept has_rebind = requires { typename Alloc::template rebind<long>; };
+
+template<typename Alloc>
+  concept has_construct = requires(Alloc& a, int* p) { a.construct(p); };
+
+template<typename Alloc>
+  concept has_destroy = requires(Alloc& a, int* p) { a.destroy(p); };
+
+template<typename Alloc>
+  concept has_max_size = requires(Alloc& a) { a.max_size(); };
+
+using A = std::allocator<int>;
+
+static_assert( !has_pointer<A> );
+static_assert( !has_const_pointer<A> );
+static_assert( !has_reference<A> );
+static_assert( !has_const_reference<A> );
+static_assert( !has_rebind<A> );
+static_assert( !has_construct<A> );
+static_assert( !has_destroy<A> );
+static_assert( !has_max_size<A> );
diff --git a/libstdc++-v3/testsuite/23_containers/deque/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/deque/capacity/29134.cc
index da5ba3575f4..2d6e13d8944 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/capacity/29134.cc
@@ -19,13 +19,15 @@
 
 #include <deque>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::deque<int> d;
 
-  VERIFY( d.max_size() == d.get_allocator().max_size() );
+  std::allocator<int> a = d.get_allocator();
+  VERIFY( d.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc b/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc
index deb71f2d51b..b36fdc81ad5 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc
@@ -21,6 +21,7 @@
 
 #include <forward_list>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 void
 test01()
@@ -40,8 +41,8 @@ test01()
   using std::_Fwd_list_node;
 #endif
 
-  VERIFY( (fld.max_size()
-	   == std::allocator<_Fwd_list_node<double> >().max_size()) );
+  std::allocator<_Fwd_list_node<double> > a;
+  VERIFY( fld.max_size() == __gnu_test::max_size(a) );
 }
 
 int
diff --git a/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc
index 1b23938c088..810d964d28a 100644
--- a/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc
@@ -19,6 +19,7 @@
 
 #include <list>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
@@ -32,7 +33,8 @@ void test01()
   using std::_List_node;
 #endif
 
-  VERIFY( l.max_size() == std::allocator<_List_node<int> >().max_size() );
+  std::allocator<_List_node<int> > a;
+  VERIFY( l.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/map/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/map/capacity/29134.cc
index c1696ba93b4..eae36f7037b 100644
--- a/libstdc++-v3/testsuite/23_containers/map/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/map/capacity/29134.cc
@@ -19,14 +19,15 @@
 
 #include <map>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::map<int, int> m;
 
-  VERIFY( (m.max_size() == std::allocator<std::_Rb_tree_node<
-	                   std::pair<const int, int> > >().max_size()) );
+  std::allocator<std::_Rb_tree_node<std::pair<const int, int> > > a;
+  VERIFY( m.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/multimap/capacity/29134.cc
index 52ab07c50b5..ac588de73f7 100644
--- a/libstdc++-v3/testsuite/23_containers/multimap/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/multimap/capacity/29134.cc
@@ -19,14 +19,15 @@
 
 #include <map>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::multimap<int, int> mm;
 
-  VERIFY( (mm.max_size() == std::allocator<std::_Rb_tree_node<
-	                    std::pair<const int, int> > >().max_size()) );
+  std::allocator<std::_Rb_tree_node<std::pair<const int, int> > > a;
+  VERIFY( mm.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/multiset/capacity/29134.cc
index 7f22a317b73..ea856a55156 100644
--- a/libstdc++-v3/testsuite/23_containers/multiset/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/multiset/capacity/29134.cc
@@ -19,14 +19,15 @@
 
 #include <set>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::multiset<int> ms;
 
-  VERIFY( ms.max_size()
-	  == std::allocator<std::_Rb_tree_node<int> >().max_size() );
+  std::allocator<std::_Rb_tree_node<int> > a;
+  VERIFY( ms.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/set/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/set/capacity/29134.cc
index f870efda727..7851ee6b7ff 100644
--- a/libstdc++-v3/testsuite/23_containers/set/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/set/capacity/29134.cc
@@ -19,14 +19,15 @@
 
 #include <set>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::set<int> s;
 
-  VERIFY( s.max_size() ==
-	  std::allocator<std::_Rb_tree_node<int> >().max_size() );
+  std::allocator<std::_Rb_tree_node<int> > a;
+  VERIFY( s.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/vector/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/vector/capacity/29134.cc
index 777e1c86238..3d3b60138d0 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/29134.cc
@@ -19,13 +19,22 @@
 
 #include <vector>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::vector<int> v;
 
-  VERIFY( v.max_size() == v.get_allocator().max_size() );
+  std::allocator<int> a = v.get_allocator();
+#if __cplusplus > 201703L
+  // std::allocator_traits::max_size() is unrealistically large,
+  // so std::vector::max_size() returns a smaller value.
+  VERIFY( v.max_size() <= __gnu_test::max_size(a) );
+#else
+  VERIFY( v.max_size() == __gnu_test::max_size(a) );
+#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 135c7080fad..b786fae9f0a 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 } }
+// { dg-do run { target { { c++11_only || c++14_only } || c++17_only } } }
 
 // 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 fe4502f49d6..5b23e5b4a2c 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 } }
+// { dg-do run { target { { c++11_only || c++14_only } || c++17_only } } }
 
 // 2007-10-26  Paolo Carlini  <pcarlini@suse.de>
 
diff --git a/libstdc++-v3/testsuite/ext/vstring/capacity/29134.cc b/libstdc++-v3/testsuite/ext/vstring/capacity/29134.cc
index cc0302b92ac..003d0406d0a 100644
--- a/libstdc++-v3/testsuite/ext/vstring/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/ext/vstring/capacity/29134.cc
@@ -19,13 +19,14 @@
 
 #include <ext/vstring.h>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   __gnu_cxx::__vstring vs;
 
-  VERIFY( vs.max_size() <= vs.get_allocator().max_size() );
+  VERIFY( vs.max_size() <= __gnu_test::max_size(vs.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/util/replacement_memory_operators.h b/libstdc++-v3/testsuite/util/replacement_memory_operators.h
index fb0b2be7dcf..cb7e7b9027b 100644
--- a/libstdc++-v3/testsuite/util/replacement_memory_operators.h
+++ b/libstdc++-v3/testsuite/util/replacement_memory_operators.h
@@ -76,7 +76,11 @@ namespace __gnu_test
     check_delete(Alloc a = Alloc())
     {
       __gnu_test::counter::exceptions(false);
+#if __cplusplus >= 201103L
+      auto p = a.allocate(10);
+#else
       typename Alloc::pointer p = a.allocate(10);
+#endif
       const std::size_t count1 = __gnu_test::counter::count();
       a.deallocate(p, 10);
       const std::size_t count2 = __gnu_test::counter::count();
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index 67e70a29edb..f3eb199d85e 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -45,6 +45,18 @@ namespace unord = std::tr1;
 
 namespace __gnu_test
 {
+  // A common API for calling max_size() on an allocator in any -std mode.
+  template<typename A>
+    typename A::size_type
+    max_size(const A& a)
+    {
+#if __cplusplus >= 201103L
+      return std::allocator_traits<A>::max_size(a);
+#else
+      return a.max_size();
+#endif
+    }
+
   class tracker_allocator_counter
   {
   public:
@@ -252,7 +264,7 @@ namespace __gnu_test
       Alloc a;
       try
 	{
-	  (void) a.allocate(a.max_size() + 1);
+	  (void) a.allocate(__gnu_test::max_size(a) + 1);
 	}
       catch(std::bad_alloc&)
 	{

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Remove redundant std::allocator members for C++20
  2019-10-22 21:40 [PATCH] Remove redundant std::allocator members for C++20 Jonathan Wakely
@ 2019-10-22 22:09 ` Jonathan Wakely
  2019-10-23 16:16   ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2019-10-22 22:09 UTC (permalink / raw)
  To: libstdc++, gcc-patches

On 22/10/19 22:40 +0100, Jonathan Wakely wrote:
>C++20 removes a number of std::allocator members that have correct
>defaults provided by std::allocator_traits, so aren't needed.
>
>Several extensions including __gnu_cxx::hash_map and tr1 containers are
>no longer usable with std::allocator in C++20 mode. They need to be
>updated to use __gnu_cxx::__alloc_traits in a follow-up patch.
>
>Tested powerpc64le-linux, committed to trunk.

I forgot to add the [[deprecated]] attribute to the members in C++17
mode, I'll do that when I fix the extensions and TR1 containers to
work in C++20 mode again.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Remove redundant std::allocator members for C++20
  2019-10-22 22:09 ` Jonathan Wakely
@ 2019-10-23 16:16   ` Jonathan Wakely
  0 siblings, 0 replies; 3+ messages in thread
From: Jonathan Wakely @ 2019-10-23 16:16 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 795 bytes --]

On 22/10/19 23:09 +0100, Jonathan Wakely wrote:
>On 22/10/19 22:40 +0100, Jonathan Wakely wrote:
>>C++20 removes a number of std::allocator members that have correct
>>defaults provided by std::allocator_traits, so aren't needed.
>>
>>Several extensions including __gnu_cxx::hash_map and tr1 containers are
>>no longer usable with std::allocator in C++20 mode. They need to be
>>updated to use __gnu_cxx::__alloc_traits in a follow-up patch.
>>
>>Tested powerpc64le-linux, committed to trunk.
>
>I forgot to add the [[deprecated]] attribute to the members in C++17
>mode, I'll do that when I fix the extensions and TR1 containers to
>work in C++20 mode again.

This fixes the extensions, but still no deprecated attribute on the
std::allocator members.

Committed to trunk.


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 16230 bytes --]

commit ea034f3d691dcd45d4ae750b69717d2cf19df6d4
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Oct 23 00:16:25 2019 +0100

    Adjust extension types to use allocator_traits
    
    This makes these extensions work with types meeting the Cpp17Allocator
    requirements as well as the C++98 Allocator requirements.
    
            * include/backward/hash_set (hash_set): Use __alloc_traits.
            * include/backward/hashtable.h (_Hashtable): Likewise.
            * include/ext/alloc_traits.h (__alloc_traits::allocate): Add overload
            taking a hint.
            * include/ext/extptr_allocator.h (_ExtPtr_allocator::allocate): Ignore
            hint.
            * include/ext/slist (_Slist_base): Use __alloc_traits.
            * include/tr1/hashtable.h (_Hashtable): Likewise.
            * include/tr1/regex (match_results): Use vector::const_reference
            instead of assuming the allocator defines it.
            * testsuite/backward/hash_map/23528.cc: Use allocator_traits in C++11.
            * testsuite/tr1/6_containers/unordered_map/capacity/29134-map.cc: Use
            __gnu_test::max_size.
            * testsuite/tr1/6_containers/unordered_multimap/capacity/
            29134-multimap.cc: Likewise.
            * testsuite/tr1/6_containers/unordered_multiset/capacity/
            29134-multiset.cc: Likewise.
            * testsuite/tr1/6_containers/unordered_set/capacity/29134-set.cc:
            Likewise.

diff --git a/libstdc++-v3/include/backward/hash_set b/libstdc++-v3/include/backward/hash_set
index 1445aa61e11..7f743fdf3af 100644
--- a/libstdc++-v3/include/backward/hash_set
+++ b/libstdc++-v3/include/backward/hash_set
@@ -88,6 +88,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
       __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
 
+      typedef __alloc_traits<_Alloc> _Alloc_traits;
+
     private:
       typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
 			_EqualKey, _Alloc> _Ht;
@@ -101,10 +103,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       
       typedef typename _Ht::size_type size_type;
       typedef typename _Ht::difference_type difference_type;
-      typedef typename _Alloc::pointer pointer;
-      typedef typename _Alloc::const_pointer const_pointer;
-      typedef typename _Alloc::reference reference;
-      typedef typename _Alloc::const_reference const_reference;
+      typedef typename _Alloc_traits::pointer pointer;
+      typedef typename _Alloc_traits::const_pointer const_pointer;
+      typedef typename _Alloc_traits::reference reference;
+      typedef typename _Alloc_traits::const_reference const_reference;
       
       typedef typename _Ht::const_iterator iterator;
       typedef typename _Ht::const_iterator const_iterator;
diff --git a/libstdc++-v3/include/backward/hashtable.h b/libstdc++-v3/include/backward/hashtable.h
index df6ad85191c..cfb9cf957d2 100644
--- a/libstdc++-v3/include/backward/hashtable.h
+++ b/libstdc++-v3/include/backward/hashtable.h
@@ -63,6 +63,7 @@
 #include <iterator>
 #include <algorithm>
 #include <bits/stl_function.h>
+#include <ext/alloc_traits.h>
 #include <backward/hash_fun.h>
 
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
@@ -280,14 +281,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef _Hashtable_node<_Val> _Node;
 
     public:
-      typedef typename _Alloc::template rebind<value_type>::other allocator_type;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<value_type>::other allocator_type;
+
       allocator_type
       get_allocator() const
       { return _M_node_allocator; }
 
     private:
-      typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
-      typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
+      typedef __gnu_cxx::__alloc_traits<allocator_type> _Alloc_traits;
+      typedef typename _Alloc_traits::template rebind<_Node>::other
+	_Node_Alloc;
+      typedef typename _Alloc_traits::template rebind<_Node*>::other
+	_Nodeptr_Alloc;
       typedef std::vector<_Node*, _Nodeptr_Alloc> _Vector_type;
 
       _Node_Alloc _M_node_allocator;
@@ -608,7 +614,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__n->_M_next = 0;
 	__try
 	  {
-	    this->get_allocator().construct(&__n->_M_val, __obj);
+	    allocator_type __a = this->get_allocator();
+	    _Alloc_traits::construct(__a, &__n->_M_val, __obj);
 	    return __n;
 	  }
 	__catch(...)
@@ -621,7 +628,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void
       _M_delete_node(_Node* __n)
       {
-	this->get_allocator().destroy(&__n->_M_val);
+	allocator_type __a = this->get_allocator();
+	_Alloc_traits::destroy(__a, &__n->_M_val);
 	_M_put_node(__n);
       }
       
diff --git a/libstdc++-v3/include/ext/alloc_traits.h b/libstdc++-v3/include/ext/alloc_traits.h
index 65fa3de271c..65340eb7acc 100644
--- a/libstdc++-v3/include/ext/alloc_traits.h
+++ b/libstdc++-v3/include/ext/alloc_traits.h
@@ -132,6 +132,11 @@ template<typename _Alloc, typename = typename _Alloc::value_type>
     allocate(_Alloc& __a, size_type __n)
     { return __a.allocate(__n); }
 
+    template<typename _Hint>
+      _GLIBCXX_NODISCARD static pointer
+      allocate(_Alloc& __a, size_type __n, _Hint __hint)
+      { return __a.allocate(__n, __hint); }
+
     static void deallocate(_Alloc& __a, pointer __p, size_type __n)
     { __a.deallocate(__p, __n); }
 
diff --git a/libstdc++-v3/include/ext/extptr_allocator.h b/libstdc++-v3/include/ext/extptr_allocator.h
index 2ce87b60c44..4e86fef81e4 100644
--- a/libstdc++-v3/include/ext/extptr_allocator.h
+++ b/libstdc++-v3/include/ext/extptr_allocator.h
@@ -92,8 +92,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT
       { return std::__addressof(__x); }
 
-      _GLIBCXX_NODISCARD pointer allocate(size_type __n, void* __hint = 0)
-      { return _M_real_alloc.allocate(__n,__hint); }
+      _GLIBCXX_NODISCARD pointer allocate(size_type __n, const void* = 0)
+      { return _M_real_alloc.allocate(__n); }
 
       void deallocate(pointer __p, size_type __n)
       { _M_real_alloc.deallocate(__p.get(), __n); }
diff --git a/libstdc++-v3/include/ext/slist b/libstdc++-v3/include/ext/slist
index 93522caf1f6..cbdfae0bd90 100644
--- a/libstdc++-v3/include/ext/slist
+++ b/libstdc++-v3/include/ext/slist
@@ -49,6 +49,7 @@
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/concept_check.h>
+#include <ext/alloc_traits.h>
 
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
@@ -251,7 +252,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
 	_Slist_node_base* __next_next = __next->_M_next;
 	__pos->_M_next = __next_next;
-	get_allocator().destroy(&__next->_M_data);
+	allocator_type __a = get_allocator();
+	__alloc_traits<allocator_type>::destroy(__a, &__next->_M_data);
 	_M_put_node(__next);
 	return __next_next;
       }
@@ -268,7 +270,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{
 	  _Slist_node<_Tp>* __tmp = __cur;
 	  __cur = (_Slist_node<_Tp>*) __cur->_M_next;
-	  get_allocator().destroy(&__tmp->_M_data);
+	  allocator_type __a = get_allocator();
+	  __alloc_traits<allocator_type>::destroy(__a, &__tmp->_M_data);
 	  _M_put_node(__tmp);
 	}
       __before_first->_M_next = __last_node;
@@ -318,7 +321,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_Node* __node = this->_M_get_node();
 	__try
 	  {
-	    get_allocator().construct(&__node->_M_data, __x);
+	    allocator_type __a = get_allocator();
+	    __alloc_traits<allocator_type>::construct(__a, &__node->_M_data,
+						      __x);
 	    __node->_M_next = 0;
 	  }
 	__catch(...)
@@ -335,7 +340,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_Node* __node = this->_M_get_node();
 	__try
 	  {
-	    get_allocator().construct(&__node->_M_data, value_type());
+	    allocator_type __a = get_allocator();
+	    __alloc_traits<allocator_type>::construct(__a, &__node->_M_data,
+						      value_type());
 	    __node->_M_next = 0;
 	  }
 	__catch(...)
@@ -481,7 +488,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	_Node* __node = (_Node*) this->_M_head._M_next;
 	this->_M_head._M_next = __node->_M_next;
-	get_allocator().destroy(&__node->_M_data);
+	allocator_type __a = get_allocator();
+	__alloc_traits<allocator_type>::destroy(__a, &__node->_M_data);
 	this->_M_put_node(__node);
       }
 
diff --git a/libstdc++-v3/include/tr1/hashtable.h b/libstdc++-v3/include/tr1/hashtable.h
index 354d7b814eb..e6455ebc3f2 100644
--- a/libstdc++-v3/include/tr1/hashtable.h
+++ b/libstdc++-v3/include/tr1/hashtable.h
@@ -126,6 +126,8 @@ namespace tr1
 					    __constant_iterators,
 					    __unique_keys> >
     {
+      typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
+
     public:
       typedef _Allocator                                  allocator_type;
       typedef _Value                                      value_type;
@@ -135,10 +137,10 @@ namespace tr1
       // hasher, if present, comes from _Hash_code_base.
       typedef typename _Allocator::difference_type        difference_type;
       typedef typename _Allocator::size_type              size_type;
-      typedef typename _Allocator::pointer                pointer;
-      typedef typename _Allocator::const_pointer          const_pointer;
-      typedef typename _Allocator::reference              reference;
-      typedef typename _Allocator::const_reference        const_reference;
+      typedef typename _Alloc_traits::pointer             pointer;
+      typedef typename _Alloc_traits::const_pointer       const_pointer;
+      typedef typename _Alloc_traits::reference           reference;
+      typedef typename _Alloc_traits::const_reference     const_reference;
 
       typedef __detail::_Node_iterator<value_type, __constant_iterators,
 				       __cache_hash_code>
@@ -162,13 +164,13 @@ namespace tr1
 
     private:
       typedef __detail::_Hash_node<_Value, __cache_hash_code> _Node;
-      typedef typename _Allocator::template rebind<_Node>::other
-							_Node_allocator_type;
-      typedef typename _Allocator::template rebind<_Node*>::other
-							_Bucket_allocator_type;
+      typedef typename _Alloc_traits::template rebind<_Node>::other
+						      _Node_allocator_type;
+      typedef typename _Alloc_traits::template rebind<_Node*>::other
+						      _Bucket_allocator_type;
 
-      typedef typename _Allocator::template rebind<_Value>::other
-							_Value_allocator_type;
+      typedef typename _Alloc_traits::template rebind<_Value>::other
+						      _Value_allocator_type;
 
       _Node_allocator_type   _M_node_allocator;
       _Node**                _M_buckets;
@@ -259,7 +261,10 @@ namespace tr1
 
       size_type
       max_size() const
-      { return _M_node_allocator.max_size(); }
+      {
+	typedef __gnu_cxx::__alloc_traits<_Node_allocator_type> _Traits;
+	return _Traits::max_size(_M_node_allocator);
+      }
 
       // Observers
       key_equal
diff --git a/libstdc++-v3/include/tr1/regex b/libstdc++-v3/include/tr1/regex
index 73c610d2bbd..01c85e99623 100644
--- a/libstdc++-v3/include/tr1/regex
+++ b/libstdc++-v3/include/tr1/regex
@@ -1789,7 +1789,7 @@ namespace regex_constants
        */
       //@{
       typedef sub_match<_Bi_iter>                             value_type;
-      typedef typename _Allocator::const_reference            const_reference;
+      typedef typename _Base_type::const_reference            const_reference;
       typedef const_reference                                 reference;
       typedef typename _Base_type::const_iterator             const_iterator;
       typedef const_iterator                                  iterator;
diff --git a/libstdc++-v3/testsuite/backward/hash_map/23528.cc b/libstdc++-v3/testsuite/backward/hash_map/23528.cc
index 01ff4bb42b2..712a65d11b9 100644
--- a/libstdc++-v3/testsuite/backward/hash_map/23528.cc
+++ b/libstdc++-v3/testsuite/backward/hash_map/23528.cc
@@ -30,9 +30,13 @@ void test01()
 
   __gnu_cxx::hash_map<int, int>::value_type *y = a.allocate(1);
 
+#if __cplusplus >= 201103L
+  std::allocator_traits<decltype(a)>::construct(a, y, *m.begin());
+  std::allocator_traits<decltype(a)>::destroy(a, y);
+#else
   a.construct(y, *m.begin());
-
   a.destroy(y);
+#endif
   a.deallocate(y, 1);
 }
 
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/capacity/29134-map.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/capacity/29134-map.cc
index 78febb07e06..0e01c0411fb 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/capacity/29134-map.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/capacity/29134-map.cc
@@ -19,14 +19,16 @@
 
 #include <tr1/unordered_map>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::tr1::unordered_map<int, int> um;
 
-  VERIFY( (um.max_size() == std::allocator<std::tr1::__detail::_Hash_node<
- 	   std::pair<const int, int>, false> >().max_size()));
+  std::allocator<std::tr1::__detail::_Hash_node<std::pair<const int, int>,
+						false> > a;
+  VERIFY( um.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/capacity/29134-multimap.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/capacity/29134-multimap.cc
index 6695fb9c5d4..f38c8df5c26 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/capacity/29134-multimap.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/capacity/29134-multimap.cc
@@ -19,14 +19,16 @@
 
 #include <tr1/unordered_map>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::tr1::unordered_multimap<int, int> umm;
 
-  VERIFY( (umm.max_size() == std::allocator<std::tr1::__detail::_Hash_node<
- 	   std::pair<const int, int>, false> >().max_size()) );
+  std::allocator<std::tr1::__detail::_Hash_node<std::pair<const int, int>,
+						false> > a;
+  VERIFY( umm.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/capacity/29134-multiset.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/capacity/29134-multiset.cc
index e9da207f1fe..01a2c00c18b 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/capacity/29134-multiset.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/capacity/29134-multiset.cc
@@ -19,14 +19,15 @@
 
 #include <tr1/unordered_set>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::tr1::unordered_multiset<int> ums;
 
-  VERIFY( (ums.max_size() == std::allocator<std::tr1::__detail::_Hash_node<
- 	   int, false> >().max_size()) );
+  std::allocator<std::tr1::__detail::_Hash_node<int, false> > a;
+  VERIFY( ums.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/capacity/29134-set.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/capacity/29134-set.cc
index 2080aaac01e..5dd133265ea 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/capacity/29134-set.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/capacity/29134-set.cc
@@ -19,14 +19,15 @@
 
 #include <tr1/unordered_set>
 #include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 // libstdc++/29134
 void test01()
 {
   std::tr1::unordered_set<int> us;
 
-  VERIFY( (us.max_size() == std::allocator<std::tr1::__detail::_Hash_node<
- 	   int, false> >().max_size()) );
+  std::allocator<std::tr1::__detail::_Hash_node<int, false> > a;
+  VERIFY( us.max_size() == __gnu_test::max_size(a) );
 }
 
 int main()

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-10-23 16:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-22 21:40 [PATCH] Remove redundant std::allocator members for C++20 Jonathan Wakely
2019-10-22 22:09 ` Jonathan Wakely
2019-10-23 16:16   ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).