mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
ADT: Fix reference invalidation in SmallVector::resize
For small enough, trivially copyable `T`, take the parameter by-value in `SmallVector::resize`. Otherwise, when growing, update the arugment appropriately. Differential Revision: https://reviews.llvm.org/D93781
This commit is contained in:
parent
1518e520f8
commit
48a93fb6cc
@ -565,7 +565,7 @@ public:
|
|||||||
/// Like resize, but \ref T is POD, the new values won't be initialized.
|
/// Like resize, but \ref T is POD, the new values won't be initialized.
|
||||||
void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
|
void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
|
||||||
|
|
||||||
void resize(size_type N, const T &NV) {
|
void resize(size_type N, ValueParamT NV) {
|
||||||
if (N == this->size())
|
if (N == this->size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -575,11 +575,8 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->assertSafeToReferenceAfterResize(&NV, N);
|
// N > this->size(). Defer to append.
|
||||||
if (this->capacity() < N)
|
this->append(N - this->size(), NV);
|
||||||
this->grow(N);
|
|
||||||
std::uninitialized_fill(this->end(), this->begin() + N, NV);
|
|
||||||
this->set_size(N);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(size_type N) {
|
void reserve(size_type N) {
|
||||||
|
@ -1135,12 +1135,14 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, Resize) {
|
|||||||
auto &V = this->V;
|
auto &V = this->V;
|
||||||
(void)V;
|
(void)V;
|
||||||
int N = this->NumBuiltinElts(V);
|
int N = this->NumBuiltinElts(V);
|
||||||
#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
|
V.resize(N + 1, V.back());
|
||||||
EXPECT_DEATH(V.resize(N + 1, V.back()), this->AssertionMessage);
|
EXPECT_EQ(N, V.back());
|
||||||
#endif
|
|
||||||
|
|
||||||
// No assertion when shrinking, since the parameter isn't accessed.
|
// Resize to add enough elements that V will grow again. If reference
|
||||||
V.resize(N - 1, V.back());
|
// invalidation breaks in the future, sanitizers should be able to catch a
|
||||||
|
// use-after-free here.
|
||||||
|
V.resize(V.capacity() + 1, V.front());
|
||||||
|
EXPECT_EQ(1, V.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPED_TEST(SmallVectorReferenceInvalidationTest, Append) {
|
TYPED_TEST(SmallVectorReferenceInvalidationTest, Append) {
|
||||||
|
Loading…
Reference in New Issue
Block a user