[libcxx-commits] [libcxx] [libcxx] retain a version of basic_string::reserve(0) that shrinks (PR #74168)
David Tenty via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Dec 18 20:42:39 PST 2023
https://github.com/daltenty updated https://github.com/llvm/llvm-project/pull/74168
>From 15a319ae34d11c61fd886de8d3a67f3dd04aafbb Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Thu, 30 Nov 2023 21:00:12 -0500
Subject: [PATCH 1/5] [libcxx] retain a version of basic_string::reserve(0)
that shrinks
Old (LLVM >=6) versions of the move assignment operator in basic string used
to (indirectly) zero the size of the string then call reserve(0) to
deallocate the memory they were holding. Implementing p0966r1 changed this by changing the contract of reserve() to never shrink, leading to memory leaks.
This PR attempts to fix this situation by:
1. reverting the shrinking behaviour in the restricted case where we reserve(0) on a zero-sized string (i.e. it has been cleared first)
2. applying an ABI-tag to reserve with the new behaviour, so uses going forward will always get the C++20+ standard compliant non-shrinking reserve in all cases
---
libcxx/include/__config | 3 ++
libcxx/include/string | 10 +++++
libcxx/lib/abi/CHANGELOG.TXT | 13 ++++++
...bcxxabi.v1.stable.exceptions.nonew.abilist | 2 +
...bcxxabi.v1.stable.exceptions.nonew.abilist | 2 +
...bcxxabi.v1.stable.exceptions.nonew.abilist | 2 +
...bcxxabi.v1.stable.exceptions.nonew.abilist | 2 +
...bcxxabi.v1.stable.exceptions.nonew.abilist | 2 +
...bcxxabi.v1.stable.exceptions.nonew.abilist | 2 +
...xxabi.v1.stable.noexceptions.nonew.abilist | 2 +
libcxx/src/CMakeLists.txt | 1 +
libcxx/src/string_compat.cpp | 25 +++++++++++
.../reserve_with_shrink.pass.cpp | 44 +++++++++++++++++++
13 files changed, 110 insertions(+)
create mode 100644 libcxx/src/string_compat.cpp
create mode 100644 libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
diff --git a/libcxx/include/__config b/libcxx/include/__config
index adff13e714cb64..98618183b2b238 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -133,6 +133,9 @@
// Re-worked external template instantiations for std::string with a focus on
// performance and fast-path inlining.
# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
+// Don't retain a copy of the old shrinking behaviour of basic_string::reserve(size_type)
+// and alter it's mangling for compatibility reasons.
+# define _LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE
// Enable clang::trivial_abi on std::unique_ptr.
# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
// Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr
diff --git a/libcxx/include/string b/libcxx/include/string
index fdffca5aed18be..0b3cae0bb59ffe 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1195,6 +1195,9 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n, value_type __c);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __n) { resize(__n, value_type()); }
+#if !defined(_LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE) && !defined(_LIBCPP_ENABLE_RESERVE_SHRINKING_ABI)
+ __attribute__((__abi_tag__("v2")))
+#endif
_LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity);
#if _LIBCPP_STD_VER >= 23
@@ -3194,11 +3197,18 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
if (__requested_capacity > max_size())
__throw_length_error();
+#if defined(_LIBCPP_ENABLE_RESERVE_SHRINKING_ABI)
+ // Shrink in the case of a zero-sized reserve on a cleared string, as we did before P0966R1,
+ // for compatibility with older versions of the move assignment operator that expected this.
+ if (!(__is_long() && __requested_capacity == 0 && size() == 0) && __requested_capacity <= capacity())
+ return;
+#else
// Make sure reserve(n) never shrinks. This is technically only required in C++20
// and later (since P0966R1), however we provide consistent behavior in all Standard
// modes because this function is instantiated in the shared library.
if (__requested_capacity <= capacity())
return;
+#endif
size_type __target_capacity = std::max(__requested_capacity, size());
__target_capacity = __recommend(__target_capacity);
diff --git a/libcxx/lib/abi/CHANGELOG.TXT b/libcxx/lib/abi/CHANGELOG.TXT
index df4e5aa3859543..9b1f5cb2d9c496 100644
--- a/libcxx/lib/abi/CHANGELOG.TXT
+++ b/libcxx/lib/abi/CHANGELOG.TXT
@@ -16,6 +16,19 @@ New entries should be added directly below the "Version" header.
Version 18.0
------------
+* [libcxx] retain a version of basic_string::reserve(0) that shrinks
+
+ This PR adds a different mangling for the version of basic_string<>::reserve(size_type) that
+ doesn't deallocates/shrinks. P0966R1 in C++20 requires we no longer do the shrink, but
+ certain versions of the move assignment operator in basic string for LLVM >= 6 used this
+ to free memory as part of the move, so we retain a restricted version of this with alternate
+ mangling for compatibility.
+
+ All platforms
+ -------------
+ Symbol added: _ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em
+ Symbol added: _ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em
+
* [libc++] Simplify the implementation of locale::id
This patch removes a symbol defined in the library for std::locale::id::__init().
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 8daad89f52e6f7..8c9afe2dfe6a1e 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -954,6 +954,7 @@
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmPKcm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmmc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc', 'type': 'FUNC'}
@@ -992,6 +993,7 @@
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmPKwm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmmw', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 91976f500539da..aace62e32776d0 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1365,6 +1365,7 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmRKS5_mm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmmc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -1403,6 +1404,7 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmPKwm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmRKS5_mm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmmw', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__grow_byEmmmmmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 8a98d42a2a1aa0..712bed447ee768 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -1365,6 +1365,7 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmPKcm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmRKS5_mm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmmc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
@@ -1403,6 +1404,7 @@
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmPKwm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmRKS5_mm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmmw', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveEm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__grow_byEmmmmmm', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'wEXP', 'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 0c06b5097b83f8..6a30e8ec7e38e0 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -954,6 +954,7 @@
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmPKcm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmmc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc', 'type': 'FUNC'}
@@ -992,6 +993,7 @@
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmPKwm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmmw', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index 16658fdff54932..b8cb2f865650f9 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -649,6 +649,7 @@
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmPKcm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmmc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc', 'type': 'FUNC'}
@@ -687,6 +688,7 @@
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmPKwm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmmw', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 49e3579614ee8c..f6918cbd83ebb0 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -647,6 +647,7 @@
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmPKcm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmmc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc', 'type': 'FUNC'}
@@ -685,6 +686,7 @@
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmPKwm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmmw', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 764e7c37daacb7..e1d67da005857e 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -619,6 +619,7 @@
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmPKcm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7replaceEmmmc', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9push_backEc', 'type': 'FUNC'}
@@ -657,6 +658,7 @@
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmPKwm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmRKS5_mm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7replaceEmmmw', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveB2v2Em', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE7reserveEm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9__grow_byEmmmmmm', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE9push_backEw', 'type': 'FUNC'}
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index be0113e6b0a585..5bf9b0fbfcead4 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -43,6 +43,7 @@ set(LIBCXX_SOURCES
ryu/f2s.cpp
stdexcept.cpp
string.cpp
+ string_compat.cpp
support/runtime/exception_fallback.ipp
support/runtime/exception_glibcxx.ipp
support/runtime/exception_libcxxabi.ipp
diff --git a/libcxx/src/string_compat.cpp b/libcxx/src/string_compat.cpp
new file mode 100644
index 00000000000000..84fd991859eef5
--- /dev/null
+++ b/libcxx/src/string_compat.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if !defined(_LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE)
+
+// Instantiate a copy of the shrinking reserve implementation to maintain ABI compatibility for older versions of
+// basic_string which relied on this behavior in move assignment.
+#define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
+#include <string>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template _LIBCPP_EXPORTED_FROM_ABI void basic_string<char>::reserve(size_type);
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template _LIBCPP_EXPORTED_FROM_ABI void basic_string<wchar_t >::reserve(size_type);
+# endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
new file mode 100644
index 00000000000000..ceac830c1af65f
--- /dev/null
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Check reserve(0) with old mangling shrinks for compatibility if it exists.
+#if !defined(_LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE)
+#define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+bool test() {
+ std::string l = "Long string so that allocation definitely, for sure, absolutely happens. Probably.";
+ const char *c = l.c_str();
+
+ assert(l.__invariants());
+
+ l.clear();
+ assert(l.__invariants());
+ assert(l.size() == 0);
+
+ l.reserve(0);
+ assert(l.__invariants());
+ assert(l.size() == 0);
+ assert(c != l.c_str());
+
+ return true;
+}
+#else
+bool test() { return true; }
+#endif
+
+int main(int, char**) {
+ test();
+ return 0;
+}
>From d912b1e8328a9e6a27739506e5767e3642daacc4 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Fri, 1 Dec 2023 22:13:56 -0500
Subject: [PATCH 2/5] clang-format
---
libcxx/src/string_compat.cpp | 8 ++++----
.../string.modifiers/reserve_with_shrink.pass.cpp | 12 ++++++------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/libcxx/src/string_compat.cpp b/libcxx/src/string_compat.cpp
index 84fd991859eef5..5d4ab6923350cb 100644
--- a/libcxx/src/string_compat.cpp
+++ b/libcxx/src/string_compat.cpp
@@ -10,15 +10,15 @@
// Instantiate a copy of the shrinking reserve implementation to maintain ABI compatibility for older versions of
// basic_string which relied on this behavior in move assignment.
-#define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
-#include <string>
+# define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
+# include <string>
_LIBCPP_BEGIN_NAMESPACE_STD
template _LIBCPP_EXPORTED_FROM_ABI void basic_string<char>::reserve(size_type);
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template _LIBCPP_EXPORTED_FROM_ABI void basic_string<wchar_t >::reserve(size_type);
-# endif
+# endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
index ceac830c1af65f..a8718567fd4a09 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
@@ -10,16 +10,16 @@
// Check reserve(0) with old mangling shrinks for compatibility if it exists.
#if !defined(_LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE)
-#define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
-#include <string>
-#include <cassert>
+# define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
+# include <string>
+# include <cassert>
-#include "test_macros.h"
-#include "min_allocator.h"
+# include "test_macros.h"
+# include "min_allocator.h"
bool test() {
std::string l = "Long string so that allocation definitely, for sure, absolutely happens. Probably.";
- const char *c = l.c_str();
+ const char* c = l.c_str();
assert(l.__invariants());
>From 731f40e26ecfff54ab0dad396f71c37a86aec142 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Fri, 15 Dec 2023 16:39:27 -0500
Subject: [PATCH 3/5] Mark test unsupported if we are using clang modules
---
.../basic.string/string.modifiers/reserve_with_shrink.pass.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
index a8718567fd4a09..89ad16acd2358e 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
@@ -8,6 +8,9 @@
// <string>
+// modules builds should follow the new ABI
+// UNSUPPORTED: clang-modules-build
+
// Check reserve(0) with old mangling shrinks for compatibility if it exists.
#if !defined(_LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE)
# define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
>From a5762a6289895ccbedaa5a25d56998c137dc97d0 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Fri, 15 Dec 2023 17:46:24 -0500
Subject: [PATCH 4/5] Include __config early in the test
so we can query the ABI version properly.
---
.../basic.string/string.modifiers/reserve_with_shrink.pass.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
index 89ad16acd2358e..677a75a16bcb26 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
@@ -11,6 +11,8 @@
// modules builds should follow the new ABI
// UNSUPPORTED: clang-modules-build
+# include <__config>
+
// Check reserve(0) with old mangling shrinks for compatibility if it exists.
#if !defined(_LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE)
# define _LIBCPP_ENABLE_RESERVE_SHRINKING_ABI
>From b2c796368d0e7295d3cef29267828b13e8d92514 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Fri, 15 Dec 2023 18:06:00 -0500
Subject: [PATCH 5/5] fix format
---
.../basic.string/string.modifiers/reserve_with_shrink.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
index 677a75a16bcb26..53e69f78f7a482 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/reserve_with_shrink.pass.cpp
@@ -11,7 +11,7 @@
// modules builds should follow the new ABI
// UNSUPPORTED: clang-modules-build
-# include <__config>
+#include <__config>
// Check reserve(0) with old mangling shrinks for compatibility if it exists.
#if !defined(_LIBCPP_ABI_DO_NOT_RETAIN_SHRINKING_RESERVE)
More information about the libcxx-commits
mailing list