[libcxx-commits] [libcxx] 479f992 - [libc++] Fix `basic_string::shrink_to_fit` for constant evaluation (#142712)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 4 16:23:52 PDT 2025


Author: A. Jiang
Date: 2025-06-05T07:23:49+08:00
New Revision: 479f9922912e3385655f0ca6e6238aaf09e6320d

URL: https://github.com/llvm/llvm-project/commit/479f9922912e3385655f0ca6e6238aaf09e6320d
DIFF: https://github.com/llvm/llvm-project/commit/479f9922912e3385655f0ca6e6238aaf09e6320d.diff

LOG: [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.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/libcxx/include/string b/libcxx/include/string
index 4f05e211919f3..67c4c537eb3b5 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -3434,8 +3434,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocat
 
   if (__fits_in_sso(__target_capacity)) {
     __annotation_guard __g(*this);
-    traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);
     __set_short_size(__size);
+    traits_type::copy(std::__to_address(__get_short_pointer()), std::__to_address(__ptr), __size + 1);
     __alloc_traits::deallocate(__alloc_, __ptr, __cap);
     return;
   }

diff  --git a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
index 9ca7825a4ba92..a3b16c8da16cb 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
@@ -19,7 +19,7 @@
 #include "test_macros.h"
 
 template <class S>
-TEST_CONSTEXPR_CXX20 void test(S s) {
+TEST_CONSTEXPR_CXX20 void test(S& s) {
   typename S::size_type old_cap = s.capacity();
   S s0                          = s;
   s.shrink_to_fit();


        


More information about the libcxx-commits mailing list