[libcxx-commits] [libcxx] db9425c - [libc++] [LIBCXX-DEBUG-FIXME] Fix an iterator-invalidation issue in string::assign.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Wed May 5 13:23:42 PDT 2021


Author: Arthur O'Dwyer
Date: 2021-05-05T16:20:53-04:00
New Revision: db9425cb060bd076fcdcbb5a37bfd992deff2086

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

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

Added: 
    

Modified: 
    libcxx/include/string
    libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/string b/libcxx/include/string
index d233369df1ab9..db29f21bdd599 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1763,11 +1763,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
 template <class _CharT, class _Traits, class _Allocator>
 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 981350f500052..f8b10c6e056cd 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
-
 // <string>
 
 // template<class InputIterator>


        


More information about the libcxx-commits mailing list