From b4e67cfd422b7e6ca079adecfa13b1055ba15b3f Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 18 Apr 2013 15:02:57 +0000 Subject: [PATCH] After years of telling people: 'If you ever find any of my code that self-move-assigns, send me a bug report.' Somebody finally took me up on it. vector::erase(begin(), begin()) does a self-move-assign of every element in the vector, leaving all of those elements in an unspecified state. I checked the other containers for this same bug and did not find it. Added test case. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@179760 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/vector | 3 ++- .../vector/vector.modifiers/erase_iter_iter.pass.cpp | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/vector b/include/vector index d1bc23e6..e04c2673 100644 --- a/include/vector +++ b/include/vector @@ -1615,7 +1615,8 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); iterator __r = __make_iter(__p); - this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p)); + if (__first != __last) + this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p)); return __r; } diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp index 1185412a..5fdcb877 100644 --- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp +++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp @@ -47,4 +47,11 @@ int main() assert(distance(l1.cbegin(), l1.cend()) == 0); assert(i == l1.begin()); } + { + std::vector > outer(2, std::vector(1)); + outer.erase(outer.begin(), outer.begin()); + assert(outer.size() == 2); + assert(outer[0].size() == 1); + assert(outer[1].size() == 1); + } }