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.
llvm-svn: 179760
This commit is contained in:
parent
cf7c55ebcc
commit
ab65a6f560
|
@ -1615,6 +1615,7 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
|
||||||
_LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
|
_LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
|
||||||
pointer __p = this->__begin_ + (__first - begin());
|
pointer __p = this->__begin_ + (__first - begin());
|
||||||
iterator __r = __make_iter(__p);
|
iterator __r = __make_iter(__p);
|
||||||
|
if (__first != __last)
|
||||||
this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
|
this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
|
||||||
return __r;
|
return __r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,4 +47,11 @@ int main()
|
||||||
assert(distance(l1.cbegin(), l1.cend()) == 0);
|
assert(distance(l1.cbegin(), l1.cend()) == 0);
|
||||||
assert(i == l1.begin());
|
assert(i == l1.begin());
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
std::vector<std::vector<int> > outer(2, std::vector<int>(1));
|
||||||
|
outer.erase(outer.begin(), outer.begin());
|
||||||
|
assert(outer.size() == 2);
|
||||||
|
assert(outer[0].size() == 1);
|
||||||
|
assert(outer[1].size() == 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue