diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -565,7 +565,7 @@ /// Like resize, but \ref T is POD, the new values won't be initialized. void resize_for_overwrite(size_type N) { resizeImpl(N); } - void resize(size_type N, const T &NV) { + void resize(size_type N, ValueParamT NV) { if (N == this->size()) return; @@ -575,11 +575,8 @@ return; } - this->assertSafeToReferenceAfterResize(&NV, N); - if (this->capacity() < N) - this->grow(N); - std::uninitialized_fill(this->end(), this->begin() + N, NV); - this->set_size(N); + // N > this->size(). Defer to append. + this->append(N - this->size(), NV); } void reserve(size_type N) { diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp @@ -1135,12 +1135,14 @@ auto &V = this->V; (void)V; int N = this->NumBuiltinElts(V); -#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST - EXPECT_DEATH(V.resize(N + 1, V.back()), this->AssertionMessage); -#endif + V.resize(N + 1, V.back()); + EXPECT_EQ(N, V.back()); - // No assertion when shrinking, since the parameter isn't accessed. - V.resize(N - 1, V.back()); + // Resize to add enough elements that V will grow again. If reference + // 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) {