From: Arthur O'Dwyer Date: Tue, 27 Apr 2021 13:10:04 +0000 (-0400) Subject: [libc++] [LIBCXX-DEBUG-FIXME] Fix an iterator-invalidation issue in string::assign. X-Git-Tag: llvmorg-14-init~7518 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db9425cb060bd076fcdcbb5a37bfd992deff2086;p=platform%2Fupstream%2Fllvm.git [libc++] [LIBCXX-DEBUG-FIXME] Fix an iterator-invalidation issue in string::assign. This appears to be a bug in our string::assign: when assigning into a longer string, from a shorter snippet of itself, we invalidate iterators before doing the copy. We should invalidate them afterward. Also drive-by improve the formatting of a function header. Differential Revision: https://reviews.llvm.org/D101675 --- diff --git a/libcxx/include/string b/libcxx/include/string index d233369..db29f21 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -1763,11 +1763,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() template inline void -basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type -#if _LIBCPP_DEBUG_LEVEL == 2 - __pos -#endif - ) +basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) { #if _LIBCPP_DEBUG_LEVEL == 2 __c_node* __c = __get_db()->__find_c_and_lock(this); @@ -1787,6 +1783,8 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type } __get_db()->unlock(); } +#else + (void)__pos; #endif // _LIBCPP_DEBUG_LEVEL == 2 } @@ -2361,12 +2359,11 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) size_type __sz = size(); __grow_by(__cap, __n - __cap, __sz, 0, __sz); } - else - __invalidate_iterators_past(__n); value_type* __p = _VSTD::__to_address(__get_pointer()); traits_type::assign(__p, __n, __c); traits_type::assign(__p[__n], value_type()); __set_size(__n); + __invalidate_iterators_past(__n); return *this; } @@ -2498,13 +2495,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For size_type __sz = size(); __grow_by(__cap, __n - __cap, __sz, 0, __sz); } - else - __invalidate_iterators_past(__n); pointer __p = __get_pointer(); for (; __first != __last; ++__first, ++__p) traits_type::assign(*__p, *__first); traits_type::assign(*__p, value_type()); __set_size(__n); + __invalidate_iterators_past(__n); } else { diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp index 981350f..f8b10c6 100644 --- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: LIBCXX-DEBUG-FIXME - // // template