Skip to content

Commit 479f992

Browse files
[libc++] Fix basic_string::shrink_to_fit for constant evaluation (#142712)
Currently, when the string shrink into the SSO buffer, the `__rep_.__s` member isn't activated before the `traits_type::copy` call yet, so internal `__builtin_memmove` call writing to the buffer causes constant evaluation failure. The existing test coverage seems a bit defective and doesn't cover this case - `shrink_to_fit` is called on the copy of string after erasure, not the original string object. This PR reorders the `__set_short_size` call, which starts the lifetime of the SSO buffer, before the copy operation. Test coverage is achieved by calling `shrink_to_fit` on the original erased string.
1 parent bac4aa4 commit 479f992

File tree

2 files changed

+2
-2
lines changed

2 files changed

+2
-2
lines changed

libcxx/include/string

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3434,8 +3434,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
34343434

34353435
if (__fits_in_sso(__target_capacity)) {
34363436
__annotation_guard __g(*this);
3437-
traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);
34383437
__set_short_size(__size);
3438+
traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);
34393439
__alloc_traits::deallocate(__alloc_, __ptr, __cap);
34403440
return;
34413441
}

libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "test_macros.h"
2020

2121
template <class S>
22-
TEST_CONSTEXPR_CXX20 void test(S s) {
22+
TEST_CONSTEXPR_CXX20 void test(S& s) {
2323
typename S::size_type old_cap = s.capacity();
2424
S s0 = s;
2525
s.shrink_to_fit();

0 commit comments

Comments
 (0)