diff --git a/libcxx/include/string b/libcxx/include/string index ede42467b99fe..ab44f25bafa0e 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -918,7 +918,14 @@ private: __rep() = default; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__short __r) : __s(__r) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__long __r) : __l(__r) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__long __r) : __s() { + // For nonstandard value_type, __s can be bigger than __l, because it + // contains at least two value_type. So if we're storing a long buffer, + // we must set the is_long flag in __s, where __is_long() will look, in + // case it isn't set by assigning to __l. + __s.__is_long_ = true; + __l = __r; + } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__uninitialized_tag) {} }; diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp index 8c2324c9d1759..34669c28d624c 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp @@ -84,9 +84,13 @@ TEST_CONSTEXPR_CXX20 bool test() { // https://llvm.org/PR31454 std::basic_string s; VeryLarge vl = {}; + LIBCPP_ASSERT(s.size() == 0); s.push_back(vl); + LIBCPP_ASSERT(s.size() == 1); s.push_back(vl); + LIBCPP_ASSERT(s.size() == 2); s.push_back(vl); + LIBCPP_ASSERT(s.size() == 3); } return true;