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.

Reply via email to