diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2023-05-10 21:30:10 +0100 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2023-05-11 21:15:22 +0100 |
commit | c62e945492afbbd2a09896fc7b0b07f7e719a606 (patch) | |
tree | f69da79bf8da6928cf08e6064a78f104d9dfac3a /libstdc++-v3/testsuite/std | |
parent | c4638cc4164ee572868dbb4f1a66dc7cfd34b8ba (diff) | |
download | gcc-c62e945492afbbd2a09896fc7b0b07f7e719a606.tar.gz |
libstdc++: Enforce value_type consistency in strings and streams
P1463R1 made it ill-formed for allocator-aware containers (including
std::basic_string) to use an allocator that has a different value_type
from the container itself. We already enforce that for other containers
(since r8-4828-g866e4d3853ccc0), but not for std::basic_string. We
traditionally accepted it as an extension and rebound the allocator, so
this change only adds the enforcement for C++20 and later.
Similarly, P1148R0 made it ill-formed for strings and streams to use a
traits type that has an incorrect char_type. We already enforce that for
std::basic_string_view, so we just need to add it to std::basic_ios and
std::basic_string.
The assertion for the allocator's value_type caused some testsuite
regressions:
FAIL: 21_strings/basic_string/cons/char/deduction.cc (test for excess errors)
FAIL: 21_strings/basic_string/cons/wchar_t/deduction.cc (test for excess errors)
FAIL: 21_strings/basic_string/requirements/explicit_instantiation/debug.cc (test for excess errors)
FAIL: 21_strings/basic_string/requirements/explicit_instantiation/int.cc (test for excess errors)
The last two are testing the traditional extension that rebinds the
allocator, so need to be disabled for C++20.
The first two are similar to LWG 3076 where an incorrect constructor is
considered for CTAD. In this case, determining that it's not viable
requires instantiating std::basic_string<Iter, char_traits<Iter>, Alloc>
which then fails the new assertion, because Alloc::value_type is not the
same as Iter. This is only a problem because the size_type parameter of
the non-viable constructor is an alias for
_Alloc_traits_impl<A>::size_type which is a nested type, and so the
enclosing basic_string specialization needs to be instantiated. If we
remove the _Alloc_traits_impl wrapper that was added in
r12-5413-g2d76292bd6719d, then the definition of size_type no longer
depends on basic_string, and we don't instantiate an invalid
specialization and don't fail the assertion. The work done by
_Alloc_traits_impl::allocate can be done in a _S_allocate function
instead, which is probably more efficient to compile anyway.
libstdc++-v3/ChangeLog:
* config/abi/pre/gnu.ver: Export basic_string::_S_allocate.
* include/bits/basic_ios.h: Add static assertion checking
traits_type::value_type.
* include/bits/basic_string.h: Likewise. Do not rebind
allocator, and add static assertion checking its value_type.
(basic_string::_Alloc_traits_impl): Remove class template.
(basic_string::_S_allocate): New static member function.
(basic_string::assign): Use _S_allocate.
* include/bits/basic_string.tcc (basic_string::_M_create)
(basic_string::reserve, basic_string::_M_replace): Likewise.
* testsuite/21_strings/basic_string/requirements/explicit_instantiation/debug.cc:
Disable for C++20 and later.
* testsuite/21_strings/basic_string/requirements/explicit_instantiation/int.cc:
Likweise.
Diffstat (limited to 'libstdc++-v3/testsuite/std')
0 files changed, 0 insertions, 0 deletions