https://gcc.gnu.org/g:6fbe9e65645f54cc564a928bc0bc69c8b421cb98
commit r15-6047-g6fbe9e65645f54cc564a928bc0bc69c8b421cb98 Author: Jonathan Wakely <jwak...@redhat.com> Date: Mon Dec 9 10:52:10 2024 +0000 libstdc++: Fix debug containers for constant evaluation [PR117962] Using a stateful allocator with std::vector would fail in Debug Mode, because the allocator-extended move constructor tries to swap all the attached safe iterators, but that uses a non-inline function which isn't constexpr. We don't actually need to swap any iterators in constant expressions, because we never attach them to the container in the first place. This bug went unnoticed because the tests for constexpr std::vector were using a stateful allocator with a std::allocator base class, but were failing to override the inherited is_always_equal trait from std::allocator. That meant that the allocators took the always-equal code paths, and didn't try to use the buggy constructor. In C++26 the std::allocator::is_always_equal trait goes away, and so the tests changed behaviour, revealing the bug. libstdc++-v3/ChangeLog: PR libstdc++/117962 * include/debug/safe_container.h: Make allocator-extended move constructor a no-op during constant evaluation. Diff: --- libstdc++-v3/include/debug/safe_container.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/debug/safe_container.h b/libstdc++-v3/include/debug/safe_container.h index 9a6c4f7ba743..75c6834bfaec 100644 --- a/libstdc++-v3/include/debug/safe_container.h +++ b/libstdc++-v3/include/debug/safe_container.h @@ -64,10 +64,13 @@ namespace __gnu_debug _Safe_container(_Safe_container&& __x, const _Alloc& __a, std::false_type) : _Safe_container() { - if (__x._M_cont().get_allocator() == __a) - _Base::_M_swap(__x); - else if (!std::__is_constant_evaluated()) - __x._M_invalidate_all(); + if (!std::__is_constant_evaluated()) + { + if (__x._M_cont().get_allocator() == __a) + _Base::_M_swap(__x); + else + __x._M_invalidate_all(); + } } protected: