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.