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

            Bug ID: 91541
           Summary: [C++17] Exception specification of operator= of
                    node-based containers may be broken
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: frankhb1989 at gmail dot com
  Target Milestone: ---

Case:

#include <utility>
#include <memory_resource>
#include <map>
#include <functional>

struct A : std::allocator<std::pair<const int, int>>
{
        template<typename U>
        struct rebind
        {
                using other = std::pmr::polymorphic_allocator<U>;
        };
};

int main()
{
        using always_equal = std::allocator_traits<A>::is_always_equal;
        using C = std::less<>;
        constexpr bool std_nothrow = always_equal::value &&
std::is_nothrow_move_assignable_v<C>;
        static_assert(std_nothrow);
        static_assert(!(std_nothrow &&
!std::is_nothrow_move_assignable<std::map<int, int, C, A>>::value));
}

The defaulted exception specification is from _Rb_tree which uses node
allocator traits instead of the allocator_traits<value_type>, so
is_always_equal::value can differ than expected.

There is a similar problem in list/forward_list::operator='s implementations:
they use the node allocator_traits explicitly, not the required exception
specification by the standard.

Reply via email to