[libcxx-commits] [libcxx] [libc++][C++03] Cherry-pick #125423 (PR #156824)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Sep 4 01:25:46 PDT 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/156824
None
>From e400878a81050af23d03a6d57740eace33af1eea Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 4 Sep 2025 10:25:27 +0200
Subject: [PATCH] [libc++][C++03] Cherry-pick #125423
---
libcxx/include/__cxx03/string | 22 +++++++++++++------
.../string.capacity/max_size.pass.cpp | 2 --
.../string.capacity/max_size.pass.cpp | 2 --
.../string_append/pointer_size.pass.cpp | 2 --
4 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/libcxx/include/__cxx03/string b/libcxx/include/__cxx03/string
index 7d54030d0b660..178140486105e 100644
--- a/libcxx/include/__cxx03/string
+++ b/libcxx/include/__cxx03/string
@@ -1101,12 +1101,20 @@ public:
_LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return size(); }
_LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
- size_type __m = __alloc_traits::max_size(__alloc());
- if (__m <= std::numeric_limits<size_type>::max() / 2) {
- return __m - __alignment;
+ if (size_type __m = __alloc_traits::max_size(__alloc()); __m <= std::numeric_limits<size_type>::max() / 2) {
+ size_type __res = __m - __alignment;
+
+ // When the __endian_factor == 2, our string representation assumes that the capacity
+ // (including the null terminator) is always even, so we have to make sure the lowest bit isn't set when the
+ // string grows to max_size()
+ if (__endian_factor == 2)
+ __res &= ~size_type(1);
+
+ // We have to allocate space for the null terminator, but max_size() doesn't include it.
+ return __res - 1;
} else {
bool __uses_lsb = __endian_factor == 2;
- return __uses_lsb ? __m - __alignment : (__m / 2) - __alignment;
+ return __uses_lsb ? __m - __alignment - 1 : (__m / 2) - __alignment - 1;
}
}
@@ -1970,11 +1978,11 @@ void basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace(
size_type __n_add,
const value_type* __p_new_stuff) {
size_type __ms = max_size();
- if (__delta_cap > __ms - __old_cap - 1)
+ if (__delta_cap > __ms - __old_cap)
__throw_length_error();
pointer __old_p = __get_pointer();
size_type __cap =
- __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
+ __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
__annotate_delete();
auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
pointer __p = __allocation.ptr;
@@ -2017,7 +2025,7 @@ void
__throw_length_error();
pointer __old_p = __get_pointer();
size_type __cap =
- __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1;
+ __old_cap < __ms / 2 - __alignment ? __recommend(std::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms;
__annotate_delete();
auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1);
pointer __p = __allocation.ptr;
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
index 7b3f81e21d8a8..6bfcb5d4bfcd8 100644
--- a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -6,8 +6,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: FROZEN-CXX03-HEADERS-FIXME
-
// <string>
// This test ensures that the correct max_size() is returned depending on the platform.
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
index ac660d8fe9941..45a52acab464e 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -8,8 +8,6 @@
// UNSUPPORTED: no-exceptions
-// XFAIL: FROZEN-CXX03-HEADERS-FIXME
-
// <string>
// size_type max_size() const; // constexpr since C++20
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
index 425a481b71639..8a13f11cf156f 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
@@ -6,8 +6,6 @@
//
//===----------------------------------------------------------------------===//
-// XFAIL: FROZEN-CXX03-HEADERS-FIXME
-
// <string>
// basic_string<charT,traits,Allocator>&
More information about the libcxx-commits
mailing list