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.