libstdc++: Begin lifetime of chars in constexpr std::string [PR103295]
authorJonathan Wakely <jwakely@redhat.com>
Thu, 18 Nov 2021 10:33:14 +0000 (10:33 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Fri, 19 Nov 2021 18:15:15 +0000 (18:15 +0000)
commit2d76292bd6719d687bc77051da265df8ed7f5a61
treef1f995d3b5c5adaa43f7cd4a722c872f03505553
parent458d2c689963d8461d84670a3d8988cd6ecbfd81
libstdc++: Begin lifetime of chars in constexpr std::string [PR103295]

Clang gives errors for constexpr std::string because the memory returned
by std::allocator<T>::allocate does not contain any objects yet, and
attempting to set them using char_traits::assign or char_traits::copy
fails with:

assignment to object outside its lifetime is not allowed in a constant expression
              *__result = *__first;
                        ^
This adds code to std::char_traits to use std::construct_at to begin
lifetimes when called during constant evaluation. To support
specializations of std::basic_string that don't use std::char_traits
there is now another layer of wrapper around the allocator_traits, so
that the lifetime of characters is begun as soon as the memory is
allocated. By doing it in the char traits and allocator traits, the rest
of basic_string can ignore the problem.

While modifying char_traits::copy and char_traits::assign to begin
lifetimes for the constexpr cases, I also replaced their uses of
std::copy and std::fill_n respectively. That means we don't need
<bits/stl_algobase.h> for char_traits.

libstdc++-v3/ChangeLog:

PR libstdc++/103295
* include/bits/basic_string.h (_Alloc_traits): Replace typedef
with struct for C++20 mode.
* include/bits/basic_string.tcc (_M_replace): Use _Alloc_traits
for allocation.
* include/bits/char_traits.h (__gnu_cxx::char_traits::assign):
Use std::_Construct during constant evaluation.
(__gnu_cxx::char_traits::assign(CharT*, const CharT*, size_t)):
Likewise. Replace std::fill_n with memset or manual loop.
(__gnu_cxx::char_traits::copy): Likewise, replacing std::copy
with memcpy.
* include/ext/vstring.h: Include <bits/stl_algobase.h> for
std::min.
* include/std/string_view: Likewise.
* testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc:
Add constexpr test.
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.tcc
libstdc++-v3/include/bits/char_traits.h
libstdc++-v3/include/ext/vstring.h
libstdc++-v3/include/std/string_view
libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc