diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -2144,6 +2144,7 @@ size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap - 1) this->__throw_length_error(); + bool __was_long = __is_long(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : @@ -2159,7 +2160,7 @@ if (__sec_cp_sz != 0) traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); - if (__old_cap+1 != __min_cap) + if (__was_long) __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); @@ -2176,6 +2177,7 @@ size_type __ms = max_size(); if (__delta_cap > __ms - __old_cap) this->__throw_length_error(); + bool __was_long = __is_long(); pointer __old_p = __get_pointer(); size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : @@ -2190,7 +2192,7 @@ traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); - if (__old_cap+1 != __min_cap) + if (__was_long) __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); @@ -3153,6 +3155,7 @@ { if (__res_arg > max_size()) this->__throw_length_error(); + bool __was_long = __is_long(); size_type __cap = capacity(); size_type __sz = size(); __res_arg = _VSTD::max(__res_arg, __sz); @@ -3161,9 +3164,8 @@ { pointer __new_data, __p; bool __was_long, __now_long; - if (__res_arg == __min_cap - 1) + if (__was_long) { - __was_long = true; __now_long = false; __new_data = __get_short_pointer(); __p = __get_long_pointer(); @@ -3826,6 +3828,8 @@ return false; if (capacity() < __min_cap - 1) return false; + if (__is_long() && capacity() < __min_cap) + return false; if (data() == 0) return false; if (data()[size()] != value_type(0))