https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96074

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|ASSIGNED                    |RESOLVED

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Your test allocator has a bug. You do not override the is_always_equal trait
from the base class, which means you inherit std::allocator<T>::is_always_equal
which is defined to be std::true_type. So the associative containers elide the
propagation:

          if (_Alloc_traits::_S_propagate_on_copy_assign())
            {
              auto& __this_alloc = this->_M_get_Node_allocator();
              auto& __that_alloc = __x._M_get_Node_allocator();
              if (!_Alloc_traits::_S_always_equal()
                  && __this_alloc != __that_alloc)
                {
                  // Replacement allocator cannot free existing storage, we
need
                  // to erase nodes first.
                  clear();
                  std::__alloc_on_copy(__this_alloc, __that_alloc);
                }
            }

If I add this to the primary template and the partial specialization then all
tests pass (including the commented-out one for std::stringbuf):

   using is_always_equal                        = std::false_type;

You have been bitten by LWG 3170: https://cplusplus.github.io/LWG/issue3170

std::allocator<T>::is_always_equal is deprecated for precisely this reason
(it's a very annoying trap) but it's still there in C++20, so you need to
override it.

Closing, as the libstdc++ containers are already correct.

Reply via email to