mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 14:25:49 +00:00
Bug 1352073: Fix off-by-one in Vector::insert; r=luke
MozReview-Commit-ID: HY0DYSAbi6M --HG-- extra : rebase_source : 15aaf8576c6c78e1dd097685947507445808ee0c extra : histedit_source : 9ece90f05a7666784a381be085a82231aef5ef29
This commit is contained in:
parent
6de398fc4f
commit
0eeedcfb9c
@ -1305,10 +1305,10 @@ Vector<T, N, AP>::insert(T* aP, U&& aVal)
|
||||
}
|
||||
} else {
|
||||
T oldBack = Move(back());
|
||||
if (!append(Move(oldBack))) { /* Dup the last element. */
|
||||
if (!append(Move(oldBack))) {
|
||||
return nullptr;
|
||||
}
|
||||
for (size_t i = oldLength; i > pos; --i) {
|
||||
for (size_t i = oldLength - 1; i > pos; --i) {
|
||||
(*this)[i] = Move((*this)[i - 1]);
|
||||
}
|
||||
(*this)[pos] = Forward<U>(aVal);
|
||||
|
@ -22,6 +22,7 @@ struct mozilla::detail::VectorTesting
|
||||
static void testReverse();
|
||||
static void testExtractRawBuffer();
|
||||
static void testExtractOrCopyRawBuffer();
|
||||
static void testInsert();
|
||||
};
|
||||
|
||||
void
|
||||
@ -141,6 +142,15 @@ struct S
|
||||
destructCount++;
|
||||
}
|
||||
|
||||
S& operator=(S&& rhs) {
|
||||
j = rhs.j;
|
||||
rhs.j = 0;
|
||||
k = Move(rhs.k);
|
||||
rhs.k.reset();
|
||||
moveCount++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
S(const S&) = delete;
|
||||
S& operator=(const S&) = delete;
|
||||
};
|
||||
@ -346,6 +356,46 @@ mozilla::detail::VectorTesting::testExtractOrCopyRawBuffer()
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void
|
||||
mozilla::detail::VectorTesting::testInsert()
|
||||
{
|
||||
S::resetCounts();
|
||||
|
||||
Vector<S, 8> vec;
|
||||
MOZ_RELEASE_ASSERT(vec.reserve(8));
|
||||
for (size_t i = 0; i < 7; i++) {
|
||||
vec.infallibleEmplaceBack(i, i * i);
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(vec.length() == 7);
|
||||
MOZ_RELEASE_ASSERT(vec.reserved() == 8);
|
||||
MOZ_RELEASE_ASSERT(S::constructCount == 7);
|
||||
MOZ_RELEASE_ASSERT(S::moveCount == 0);
|
||||
MOZ_RELEASE_ASSERT(S::destructCount == 0);
|
||||
|
||||
S s(42, 43);
|
||||
MOZ_RELEASE_ASSERT(vec.insert(vec.begin() + 4, Move(s)));
|
||||
|
||||
for (size_t i = 0; i < vec.length(); i++) {
|
||||
const S& s = vec[i];
|
||||
MOZ_RELEASE_ASSERT(s.k);
|
||||
if (i < 4)
|
||||
MOZ_RELEASE_ASSERT(s.j == i && *s.k == i * i);
|
||||
else if (i == 4)
|
||||
MOZ_RELEASE_ASSERT(s.j == 42 && *s.k == 43);
|
||||
else
|
||||
MOZ_RELEASE_ASSERT(s.j == i - 1 && *s.k == (i - 1) * (i - 1));
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(vec.length() == 8);
|
||||
MOZ_RELEASE_ASSERT(vec.reserved() == 8);
|
||||
MOZ_RELEASE_ASSERT(S::constructCount == 8);
|
||||
MOZ_RELEASE_ASSERT(S::moveCount == 1 /* move in insert() call */ +
|
||||
1 /* move the back() element */ +
|
||||
3 /* elements to shift */);
|
||||
MOZ_RELEASE_ASSERT(S::destructCount == 1);
|
||||
}
|
||||
|
||||
// Declare but leave (permanently) incomplete.
|
||||
struct Incomplete;
|
||||
|
||||
@ -398,4 +448,5 @@ main()
|
||||
VectorTesting::testReverse();
|
||||
VectorTesting::testExtractRawBuffer();
|
||||
VectorTesting::testExtractOrCopyRawBuffer();
|
||||
VectorTesting::testInsert();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user