summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qcontainertools_impl.h
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2023-02-28 10:35:18 +0100
committerMarc Mutz <marc.mutz@qt.io>2023-12-07 05:16:24 +0000
commitff7d69dafda2f2cdc3a93f76ed8f77a113ac1a1c (patch)
tree0299c86328f57f710ef82b8dd10775eb1d95461a /src/corelib/tools/qcontainertools_impl.h
parent2d052b038d5c3e8ec55ca12b3ba531208a6d3cf1 (diff)
Refuse to relocate non-copy/move-constructible types
When a type was explicitly made non-copyable and non-movable, refuse attempts to mark it as relocatable. Trivial relocatability is an optimization for move+destroy, so we shouldn't allow working around the class author's wish to have a non-movable type by a user making it Q_RELOCATABLE_TYPE. Therefore, add a static_assert() to Q_DECLARE_TYPEINFO that fires when a non-copy/move-constructible type is made Q_RELOCATABLE_TYPE. Also add a similar static assertion to QTypeInfoMerger: All members of a class T may be Q_RELOCATABLE_TYPE. But that doesn't mean that T itself is: class T { QString m_s; QByteArray m_b; Q_DISABLE_COPY(T) public: ~~~~ }; so check that T is actually copyable (or movable) when QTypeInfoMerger would have have yielded isRelocatable. Since Q_DECLARE_TYPEINFO and QTypeInfoMerger are not the only ways in which a user can mark a type as relocatable (manual QTypeInfo specialization is another option, and required, for certain template classes), also check in q_uninitialized_relocate_n(). [ChangeLog][QtCore][QTypeInfo/QTypeInfoMerger] No longer allows marking as Q_RELOCATABLE_TYPE a type that is neither movable nor copyable. Change-Id: If6b3e5c1bfb6538bd280262eefbb08ba3c810e4c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qcontainertools_impl.h')
-rw-r--r--src/corelib/tools/qcontainertools_impl.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h
index 40ed0a84e9..d66705ef4d 100644
--- a/src/corelib/tools/qcontainertools_impl.h
+++ b/src/corelib/tools/qcontainertools_impl.h
@@ -72,6 +72,8 @@ template <typename T, typename N>
void q_uninitialized_relocate_n(T* first, N n, T* out)
{
if constexpr (QTypeInfo<T>::isRelocatable) {
+ static_assert(std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>,
+ "Refusing to relocate this non-copy/non-move-constructible type.");
if (n != N(0)) { // even if N == 0, out == nullptr or first == nullptr are UB for memcpy()
std::memcpy(static_cast<void *>(out),
static_cast<const void *>(first),