diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1786,7 +1786,7 @@ allocator_type __a = __str.__alloc(); auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); __begin_lifetime(__allocation.ptr, __allocation.count); - __clear_and_shrink(); + __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); __alloc() = std::move(__a); __set_long_pointer(__allocation.ptr); __set_long_cap(__allocation.count); @@ -4050,9 +4050,7 @@ if(__is_long()) { __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); - __set_long_cap(0); - __set_short_size(0); - traits_type::assign(*__get_short_pointer(), value_type()); + __default_init(); } } diff --git a/libcxx/test/libcxx/strings/basic.string/string.capacity/PR53170.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.capacity/PR53170.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.capacity/PR53170.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.capacity/PR53170.pass.cpp @@ -33,9 +33,9 @@ #include "min_allocator.h" template -void test() { +TEST_CONSTEXPR_CXX20 bool test() { // Test that a call to reserve() does shrink the string. - { + if (!TEST_IS_CONSTANT_EVALUATED) { S s(1000, 'a'); typename S::size_type old_cap = s.capacity(); s.resize(20); @@ -66,6 +66,8 @@ s.reserve(0); assert(s.capacity() == old_cap); } + + return true; } int main(int, char**) { @@ -75,5 +77,9 @@ test, min_allocator > >(); #endif +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.capacity/max_size.pass.cpp @@ -20,7 +20,8 @@ // alignment of the string heap buffer is hardcoded to 16 static const size_t alignment = 16; -void full_size() { +template +TEST_CONSTEXPR_CXX20 void full_size() { std::string str; assert(str.max_size() == std::numeric_limits::max() - alignment); @@ -40,7 +41,8 @@ assert(u32str.max_size() == std::numeric_limits::max() / 4 - alignment); } -void half_size() { +template +TEST_CONSTEXPR_CXX20 void half_size() { std::string str; assert(str.max_size() == std::numeric_limits::max() / 2 - alignment); @@ -60,7 +62,7 @@ assert(u32str.max_size() == std::numeric_limits::max() / 4 - alignment); } -bool test() { +TEST_CONSTEXPR_CXX20 bool test() { #if _LIBCPP_ABI_VERSION == 1 @@ -100,7 +102,7 @@ int main(int, char**) { test(); #if TEST_STD_VER > 17 - // static_assert(test()); + static_assert(test()); #endif return 0; diff --git a/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp @@ -18,8 +18,7 @@ #include "min_allocator.h" template -void -test() +TEST_CONSTEXPR_CXX20 bool test() { // Tests that a long string holding a SSO size string results in // an SSO copy constructed value. @@ -29,21 +28,19 @@ LIBCPP_ASSERT(s2.__invariants()); assert(s2 == s1); assert(s2.capacity() < sizeof(S)); + + return true; } int main(int, char**) { - { - typedef test_allocator A; - typedef std::basic_string, A> S; - test(); - } + test, test_allocator > >(); #if TEST_STD_VER >= 11 - { - typedef min_allocator A; - typedef std::basic_string, A> S; - test(); - } + test, min_allocator>>(); +#endif +#if TEST_STD_VER > 17 + static_assert(test, test_allocator>>()); + static_assert(test, min_allocator>>()); #endif return 0; diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/clear_and_shrink.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/clear_and_shrink.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/clear_and_shrink.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/clear_and_shrink.pass.cpp @@ -15,25 +15,31 @@ #include "test_macros.h" -int main(int, char**) -{ - std::string l = "Long string so that allocation definitely, for sure, absolutely happens. Probably."; - std::string s = "short"; +TEST_CONSTEXPR_CXX20 bool test() { + std::string l = "Long string so that allocation definitely, for sure, absolutely happens. Probably."; + std::string s = "short"; + + assert(l.__invariants()); + assert(s.__invariants()); - assert(l.__invariants()); - assert(s.__invariants()); + s.__clear_and_shrink(); + assert(s.__invariants()); + assert(s.size() == 0); - s.__clear_and_shrink(); - assert(s.__invariants()); - assert(s.size() == 0); + std::string::size_type cap = l.capacity(); + l.__clear_and_shrink(); + assert(l.__invariants()); + assert(l.size() == 0); + assert(l.capacity() < cap); - { - std::string::size_type cap = l.capacity(); - l.__clear_and_shrink(); - assert(l.__invariants()); - assert(l.size() == 0); - assert(l.capacity() < cap); - } + return true; +} - return 0; +int main(int, char**) +{ + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp @@ -15,14 +15,14 @@ #include "test_macros.h" -void write_c_str(char *buf, int size) { +TEST_CONSTEXPR_CXX20 void write_c_str(char *buf, int size) { for (int i=0; i < size; ++i) { buf[i] = 'a'; } buf[size] = '\0'; } -void test_buffer_usage() +TEST_CONSTEXPR_CXX20 void test_buffer_usage() { { unsigned buff_size = 125; @@ -31,7 +31,7 @@ s.__resize_default_init(buff_size); write_c_str(&s[0], used_size); assert(s.size() == buff_size); - assert(strlen(s.data()) == used_size); + assert(std::char_traits().length(s.data()) == used_size); s.__resize_default_init(used_size); assert(s.size() == used_size); assert(s.data()[used_size] == '\0'); @@ -41,7 +41,7 @@ } } -void test_basic() { +TEST_CONSTEXPR_CXX20 void test_basic() { { std::string s; s.__resize_default_init(3); @@ -56,9 +56,18 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX20 bool test() { test_basic(); test_buffer_usage(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; }