[libcxx-commits] [libcxx] [libc++] Introduce basic_string::__allocate_long_buffer_for_growing (PR #162633)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Sep 8 22:57:42 PDT 2026


================
@@ -2714,14 +2727,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::__
     size_type __n_del,
     size_type __n_add,
     const value_type* __p_new_stuff) {
-  size_type __ms = max_size();
-  if (__delta_cap > __ms - __old_cap)
-    __throw_length_error();
+  __long __buffer = __allocate_long_buffer(__alloc_, __get_amortized_growth_capacity(__old_cap + __delta_cap));
----------------
Himadhith wrote:

This change is causing a failure on AIX, the result of `__old_cap + __delta_cap` is being warped before it gets passed to `__get_amortized_growth_capacity` making the end comparison not what we think it's doing.   
Verified that the old guard does not face this issue. 

```
#include <string>
#include <cstdio>
#include <stdexcept>
int main() {
  std::string s("hello");
  typedef std::string::size_type SZ;
  SZ old_cap   = s.capacity();
  SZ sz        = s.size();
  SZ n         = std::string::npos;
  SZ delta_cap = sz + n - old_cap;
  SZ arg       = old_cap + delta_cap;
  SZ ms        = s.max_size();
}
[himadhit: ~/test] $ ./test_wrap2_dc
old_cap                      = 22
sz                           = 5
n (npos)                     = 18446744073709551615
sz + n                       = 4
delta_cap (sz+n-old_cap)     = 18446744073709551598
old_cap + delta_cap          = 4
max_size()                   = 9223372036854775798
ms - old_cap                 = 9223372036854775776
delta_cap > ms-old_cap       = 1  (old guard: FIRES -> length_error)
arg > ms                     = 0  (new guard: NO - MISSED)
```

CC: @philnik777 

https://github.com/llvm/llvm-project/pull/162633


More information about the libcxx-commits mailing list