12
12
13
13
// void shrink_to_fit(); // constexpr since C++20
14
14
15
- // Make sure we use an allocation returned by allocate_at_least if it is smaller than the current allocation
16
- // even if it contains more bytes than we requested
17
-
18
15
#include < cassert>
19
16
#include < string>
20
17
18
+ #include " asan_testing.h"
19
+ #include " increasing_allocator.h"
20
+
21
21
template <typename T>
22
22
struct oversizing_allocator {
23
23
using value_type = T;
@@ -37,6 +37,9 @@ bool operator==(oversizing_allocator<T>, oversizing_allocator<U>) {
37
37
return true ;
38
38
}
39
39
40
+ // Make sure we use an allocation returned by allocate_at_least if it is smaller than the current allocation
41
+ // even if it contains more bytes than we requested.
42
+ // Fix issue: https://github.com/llvm/llvm-project/pull/115659
40
43
void test_oversizing_allocator () {
41
44
std::basic_string<char , std::char_traits<char >, oversizing_allocator<char >> s{
42
45
" String does not fit in the internal buffer and is a bit longer" };
@@ -48,8 +51,37 @@ void test_oversizing_allocator() {
48
51
assert (s.size () == size);
49
52
}
50
53
54
+ // Ensure that the libc++ implementation of shrink_to_fit does NOT swap buffer with equal allocation sizes
55
+ void test_no_swap_with_equal_allocation_size () {
56
+ { // Test with custom allocator with a minimum allocation size
57
+ std::basic_string<char , std::char_traits<char >, min_size_allocator<128 , char > > s (
58
+ " A long string exceeding SSO limit but within min alloc size" );
59
+ std::size_t capacity = s.capacity ();
60
+ std::size_t size = s.size ();
61
+ auto data = s.data ();
62
+ s.shrink_to_fit ();
63
+ assert (s.capacity () <= capacity);
64
+ assert (s.size () == size);
65
+ assert (is_string_asan_correct (s));
66
+ assert (s.capacity () == capacity && s.data () == data);
67
+ }
68
+ { // Test with custom allocator with a minimum power of two allocation size
69
+ std::basic_string<char , std::char_traits<char >, pow2_allocator<char > > s (
70
+ " This is a long string that exceeds the SSO limit" );
71
+ std::size_t capacity = s.capacity ();
72
+ std::size_t size = s.size ();
73
+ auto data = s.data ();
74
+ s.shrink_to_fit ();
75
+ assert (s.capacity () <= capacity);
76
+ assert (s.size () == size);
77
+ assert (is_string_asan_correct (s));
78
+ assert (s.capacity () == capacity && s.data () == data);
79
+ }
80
+ }
81
+
51
82
int main (int , char **) {
52
83
test_oversizing_allocator ();
84
+ test_no_swap_with_equal_allocation_size ();
53
85
54
86
return 0 ;
55
87
}
0 commit comments