diff --git a/libcxx/include/__string/extern_template_lists.h b/libcxx/include/__string/extern_template_lists.h --- a/libcxx/include/__string/extern_template_lists.h +++ b/libcxx/include/__string/extern_template_lists.h @@ -104,7 +104,6 @@ _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \ _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \ _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \ - _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \ _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \ _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias(value_type const*, size_type)) \ _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias(value_type const*, size_type)) \ diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1791,7 +1791,7 @@ } else { - __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); + __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); __p = std::__to_address(__get_long_pointer()); } __sz += __n; @@ -1919,8 +1919,15 @@ void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz); _LIBCPP_CONSTEXPR_SINCE_CXX20 +#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 + _LIBCPP_HIDE_FROM_ABI +#endif + _LIBCPP_DEPRECATED_("use __grow_by_without_replace") void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add = 0); + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + void __grow_by_without_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz, + size_type __n_copy, size_type __n_del, size_type __n_add = 0); _LIBCPP_CONSTEXPR_SINCE_CXX20 void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, @@ -2336,9 +2343,16 @@ traits_type::assign(__p[__old_sz], value_type()); } +// __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it +// may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is +// not removed or changed to avoid breaking the ABI. template void _LIBCPP_CONSTEXPR_SINCE_CXX20 +#if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 + _LIBCPP_HIDE_FROM_ABI +#endif + _LIBCPP_DEPRECATED_("use __grow_by_without_replace") basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, size_type __n_copy, size_type __n_del, size_type __n_add) { @@ -2366,6 +2380,21 @@ __set_long_cap(__allocation.count); } +template +void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI +basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace( + size_type __old_cap, + size_type __delta_cap, + size_type __old_sz, + size_type __n_copy, + size_type __n_del, + size_type __n_add) { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add); + _LIBCPP_SUPPRESS_DEPRECATED_POP + __set_long_size(__old_sz - __n_del + __n_add); +} + // assign template @@ -2424,7 +2453,7 @@ if (__cap < __n) { size_type __sz = size(); - __grow_by(__cap, __n - __cap, __sz, 0, __sz); + __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); } value_type* __p = std::__to_address(__get_pointer()); traits_type::assign(__p, __n, __c); @@ -2568,7 +2597,7 @@ // 2. In the exotic case where the input range is the byte representation of the string itself, the string // object itself stays valid even if reallocation happens. size_type __sz = size(); - __grow_by(__cap, __n - __cap, __sz, 0, __sz); + __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); } pointer __p = __get_pointer(); for (; __first != __last; ++__p, (void) ++__first) @@ -2657,7 +2686,7 @@ size_type __cap = capacity(); size_type __sz = size(); if (__cap - __sz < __n) - __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); + __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); pointer __p = __get_pointer(); traits_type::assign(std::__to_address(__p) + __sz, __n, __c); __sz += __n; @@ -2676,7 +2705,7 @@ size_type __cap = capacity(); size_type __sz = size(); if (__cap - __sz < __n) - __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); + __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); pointer __p = __get_pointer(); __sz += __n; __set_size(__sz); @@ -2704,7 +2733,7 @@ } if (__sz == __cap) { - __grow_by(__cap, 1, __sz, __sz, 0); + __grow_by_without_replace(__cap, 1, __sz, __sz, 0); __is_short = false; // the string is always long after __grow_by } pointer __p = __get_pointer(); @@ -2737,7 +2766,7 @@ !__addr_in_range(*__first)) { if (__cap - __sz < __n) - __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); + __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); pointer __p = __get_pointer() + __sz; for (; __first != __last; ++__p, (void) ++__first) traits_type::assign(*__p, *__first); @@ -2850,7 +2879,7 @@ } else { - __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); + __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); __p = std::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n, __c); @@ -2946,7 +2975,7 @@ value_type* __p; if (__cap == __sz) { - __grow_by(__cap, 1, __sz, __ip, 0, 1); + __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1); __p = std::__to_address(__get_long_pointer()); } else @@ -3037,7 +3066,7 @@ } else { - __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); + __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); __p = std::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n2, __c);