1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +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:
Duncan P. N. Exon Smith 2020-11-19 17:12:27 -08:00
parent 1518e520f8
commit 48a93fb6cc
2 changed files with 10 additions and 11 deletions

View File

@ -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) {

View File

@ -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) {