@@ -61,28 +61,54 @@ TEST_CONSTEXPR_CXX20 bool test() {
6161 test_string<std::basic_string<char , std::char_traits<char >, safe_allocator<char >>>();
6262#endif
6363
64- return true ;
65- }
66-
6764#if TEST_STD_VER >= 23
68- // https://github.com/llvm/llvm-project/issues/95161
69- void test_increasing_allocator () {
70- std::basic_string<char , std::char_traits<char >, increasing_allocator<char >> s{
71- " String does not fit in the internal buffer" };
72- std::size_t capacity = s.capacity ();
73- std::size_t size = s.size ();
74- s.shrink_to_fit ();
75- assert (s.capacity () <= capacity);
76- assert (s.size () == size);
77- LIBCPP_ASSERT (is_string_asan_correct (s));
65+ { // Make sure shrink_to_fit never increases capacity
66+ // See: https://github.com/llvm/llvm-project/issues/95161
67+ std::basic_string<char , std::char_traits<char >, increasing_allocator<char >> s{
68+ " String does not fit in the internal buffer" };
69+ std::size_t capacity = s.capacity ();
70+ std::size_t size = s.size ();
71+ s.shrink_to_fit ();
72+ assert (s.capacity () <= capacity);
73+ assert (s.size () == size);
74+ LIBCPP_ASSERT (is_string_asan_correct (s));
75+ }
76+ #endif
77+
78+ { // Ensure that the libc++ implementation of shrink_to_fit does NOT swap buffer with equal allocation sizes
79+ { // Test with custom allocator with a minimum allocation size
80+ std::basic_string<char , std::char_traits<char >, min_size_allocator<128 , char > > s (
81+ " A long string exceeding SSO limit but within min alloc size" );
82+ std::size_t capacity = s.capacity ();
83+ std::size_t size = s.size ();
84+ auto data = s.data ();
85+ s.shrink_to_fit ();
86+ assert (s.capacity () <= capacity);
87+ assert (s.size () == size);
88+ LIBCPP_ASSERT (is_string_asan_correct (s));
89+ if (s.capacity () == capacity)
90+ LIBCPP_ASSERT (s.data () == data);
91+ }
92+ { // Test with custom allocator with a minimum power of two allocation size
93+ std::basic_string<char , std::char_traits<char >, pow2_allocator<char > > s (
94+ " This is a long string that exceeds the SSO limit" );
95+ std::size_t capacity = s.capacity ();
96+ std::size_t size = s.size ();
97+ auto data = s.data ();
98+ s.shrink_to_fit ();
99+ assert (s.capacity () <= capacity);
100+ assert (s.size () == size);
101+ LIBCPP_ASSERT (is_string_asan_correct (s));
102+ if (s.capacity () == capacity)
103+ LIBCPP_ASSERT (s.data () == data);
104+ }
105+ }
106+
107+ return true ;
78108}
79- #endif // TEST_STD_VER >= 23
80109
81110int main (int , char **) {
82111 test ();
83- #if TEST_STD_VER >= 23
84- test_increasing_allocator ();
85- #endif
86112#if TEST_STD_VER > 17
87113 static_assert (test ());
88114#endif
0 commit comments