https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128115
Bug ID: 128115
Summary: Debug Mode range assign/insert and std::copy rejected
in constant expressions
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: mishmish at mishmish dot dev
CC: fdumont at gcc dot gnu.org, jakub at gcc dot gnu.org,
jwakely at redhat dot com
Target Milestone: ---
Created attachment 65945
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65945&action=edit
6 failing static assertions
With -D_GLIBCXX_DEBUG, these are rejected in constant expressions:
std::vector<int> a{1, 2}, v(2);
int s[2]{1, 2};
v.assign(a.begin(), a.end()); // (1)
v.insert(v.end(), a.begin(), a.end()); // (1)
std::copy(s, s + 2, v.begin()); // (2)
std::move(s, s + 2, v.begin()); // (2)
std::copy_backward(s, s + 2, v.end()); // (2)
std::equal(s, s + 2, v.begin()); // (2)
Testcase: https://godbolt.org/z/zPWxKE4cW
$ g++ -std=c++20 -D_GLIBCXX_DEBUG -fsyntax-only testcase.cc
Every static_assert fails on 15.3, 16.2 and trunk, with -std=c++20,
c++23 and c++26. All pass without -D_GLIBCXX_DEBUG.
(1) debug/vector calls __gnu_debug::__unsafe during constant
evaluation, but the _Safe_iterator overload of __unsafe is not
constexpr.
Fix: add _GLIBCXX20_CONSTEXPR to that overload in
debug/safe_iterator.h.
(2) The Debug Mode overloads of __copy_move_a, __copy_move_backward_a
and __equal_aux in debug/safe_iterator.tcc call _M_can_advance,
which is not constexpr. It can't be made constexpr because it
calls _M_singular, which is defined in the library.
Fix: skip the _M_can_advance calls in that file when
std::__is_constant_evaluated(), as __can_advance already does.
The code then takes its existing constexpr path.
I'll send a patch. It also fixes constexpr deque/inplace_vector for
the relevant versions of gcc and the standard.