Skip to content

Commit e400878

Browse files
committed
[libc++][C++03] Cherry-pick llvm#125423
1 parent 010f1ea commit e400878

File tree

4 files changed

+15
-13
lines changed

4 files changed

+15
-13
lines changed

libcxx/include/__cxx03/string

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,12 +1101,20 @@ public:
11011101
_LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return size(); }
11021102

11031103
_LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
1104-
size_type __m = __alloc_traits::max_size(__alloc());
1105-
if (__m <= std::numeric_limits<size_type>::max() / 2) {
1106-
return __m - __alignment;
1104+
if (size_type __m = __alloc_traits::max_size(__alloc()); __m <= std::numeric_limits<size_type>::max() / 2) {
1105+
size_type __res = __m - __alignment;
1106+
1107+
// When the __endian_factor == 2, our string representation assumes that the capacity
1108+
// (including the null terminator) is always even, so we have to make sure the lowest bit isn't set when the
1109+
// string grows to max_size()
1110+
if (__endian_factor == 2)
1111+
__res &= ~size_type(1);
1112+
1113+
// We have to allocate space for the null terminator, but max_size() doesn't include it.
1114+
return __res - 1;
11071115
} else {
11081116
bool __uses_lsb = __endian_factor == 2;
1109-
return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
1117+
return __uses_lsb ? __m - __alignment - 1 : (__m / 2) - __alignment - 1;
11101118
}
11111119
}
11121120

@@ -1970,11 +1978,11 @@ void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace(
19701978
size_type __n_add,
19711979
const value_type* __p_new_stuff) {
19721980
size_type __ms = max_size();
1973-
if (__delta_cap > __ms - __old_cap - 1)
1981+
if (__delta_cap > __ms - __old_cap)
19741982
__throw_length_error();
19751983
pointer __old_p = __get_pointer();
19761984
size_type __cap =
1977-
__old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
1985+
__old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
19781986
__annotate_delete();
19791987
auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
19801988
pointer __p = __allocation.ptr;
@@ -2017,7 +2025,7 @@ void
20172025
__throw_length_error();
20182026
pointer __old_p = __get_pointer();
20192027
size_type __cap =
2020-
__old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
2028+
__old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
20212029
__annotate_delete();
20222030
auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
20232031
pointer __p = __allocation.ptr;

libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
10-
119
// <string>
1210

1311
// This test ensures that the correct max_size() is returned depending on the platform.

libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
// UNSUPPORTED: no-exceptions
1010

11-
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
12-
1311
// <string>
1412

1513
// size_type max_size() const; // constexpr since C++20

libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
10-
119
// <string>
1210

1311
// basic_string<charT,traits,Allocator>&

0 commit comments

Comments
 (0)