[PATCH] D115443: [ADT] Weaken the initialization condition in SmallVector::resize_for_overwrite
Benjamin Kramer via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 9 06:12:59 PST 2021
bkramer created this revision.
bkramer added reviewers: dexonsmith, njames93.
bkramer requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
This method was originally modeled after std::make_unique_for_overwrite, which
default initializes everything, making it a lot less useful.
Using is_trivially_copyable as the condition gives uninitialized memory for
classes that have a default constructor but still allows using
resize_for_overwrite for classes with a non-trivial assignment operator or
destructor. In other words, it makes
SmallVector<std::unique_ptr>::resize_for_overwrite safe and
SmallVector<clang::SourceLocation>::resize_for_overwrite efficient.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D115443
Files:
llvm/include/llvm/ADT/SmallVector.h
llvm/unittests/ADT/SmallVectorTest.cpp
Index: llvm/unittests/ADT/SmallVectorTest.cpp
===================================================================
--- llvm/unittests/ADT/SmallVectorTest.cpp
+++ llvm/unittests/ADT/SmallVectorTest.cpp
@@ -392,6 +392,33 @@
V.resize(V.size() + 1);
EXPECT_EQ(0U, V.back());
}
+ {
+ struct DefaultConstructible {
+ unsigned U = 10;
+ };
+ SmallVector<DefaultConstructible> V;
+ V.push_back({5U});
+ V.pop_back();
+ V.resize_for_overwrite(V.size() + 1U);
+ EXPECT_EQ(5U, V.back().U);
+ V.pop_back();
+ V.resize(V.size() + 1);
+ EXPECT_EQ(10U, V.back().U);
+ }
+ {
+ struct DefaultConstructible {
+ unsigned U = 20;
+ ~DefaultConstructible() {}
+ };
+ SmallVector<DefaultConstructible> V;
+ V.push_back({5U});
+ V.pop_back();
+ V.resize_for_overwrite(V.size() + 1U);
+ EXPECT_EQ(20U, V.back().U);
+ V.pop_back();
+ V.resize(V.size() + 1);
+ EXPECT_EQ(20U, V.back().U);
+ }
}
// Overflow past fixed size.
Index: llvm/include/llvm/ADT/SmallVector.h
===================================================================
--- llvm/include/llvm/ADT/SmallVector.h
+++ llvm/include/llvm/ADT/SmallVector.h
@@ -598,10 +598,8 @@
}
this->reserve(N);
- for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
- if (ForOverwrite)
- new (&*I) T;
- else
+ if (!ForOverwrite || !is_trivially_copyable<T>::value)
+ for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
new (&*I) T();
this->set_size(N);
}
@@ -609,7 +607,9 @@
public:
void resize(size_type N) { resizeImpl<false>(N); }
- /// Like resize, but \ref T is POD, the new values won't be initialized.
+ /// Like resize, but if \ref T is trivially copyable, the new values won't be
+ /// initialized. This is similar in spirit to std::make_unique_for_overwrite,
+ /// but does not default initialize.
void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
/// Like resize, but requires that \p N is less than \a size().
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115443.393136.patch
Type: text/x-patch
Size: 2046 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211209/6d67e95e/attachment.bin>
More information about the llvm-commits
mailing list