Skip to content

Commit 896fbb9

Browse files
[libc++] Fix basic_string::shrink_to_fit for constant evaluation
Currently, when the string shrink into the SSO buffer, the lifetime of the buffer hasn't begun before copying characters into it, so the subsequent copy operation raises UB and thus causes constant evaluation failure. The existing test coverage seems a bit defective - `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 6760857 commit 896fbb9

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)