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

            Bug ID: 117962
           Summary: Debug Mode containers with stateful allocators don't
                    work in constexpr
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

This fails with -std=c++20 -D_GLIBCXX_DEBUG

#include <memory>
#include <vector>

template<typename T>
struct Alloc : std::allocator<T>
{
  using std::allocator<T>::allocator;

  constexpr explicit Alloc(int p) : personality(p) { }

  template<typename U>
    constexpr Alloc(const Alloc<U>& a) : personality(a.personality) { }

  using is_always_equal = std::false_type;

  int personality = 0;

  constexpr bool operator==(const Alloc& a) const noexcept
  { return personality == a.personality; }
};

constexpr bool
move_constructor()
{
  std::vector<long, Alloc<long>> l1;
  std::vector<long, Alloc<long>> l2(std::move(l1), l1.get_allocator());
  return true;
}

static_assert( move_constructor() );


debug/safe_container.h:68:25: error: call to non-'constexpr' function 'void
__gnu_debug::_Safe_sequence_base::_M_swap(__gnu_debug::_Safe_sequence_base&)'
   68 |           _Base::_M_swap(__x);
      |           ~~~~~~~~~~~~~~^~~~~


That _M_swap function can't be constexpr unless we move its definition inline,
as it's currently in src/c++11/debug.o

Maybe the allocator-extended move constructor that uses _M_swap could be
re-specified in terms of move assignment of the base subobject.

Reply via email to