diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index b84cd7e2749..d1b95be0e63 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -305,11 +305,18 @@ static QVariant::Private clonePrivate(const QVariant::Private &other) if (d.is_shared) { d.data.shared->ref.ref(); } else if (const QtPrivate::QMetaTypeInterface *iface = d.typeInterface()) { - Q_ASSERT(d.canUseInternalSpace(iface)); + if (Q_LIKELY(d.canUseInternalSpace(iface))) { + // if not trivially copyable, ask to copy (if it's trivially + // copyable, we've already copied it) + if (iface->copyCtr) + QtMetaTypePrivate::copyConstruct(iface, d.data.data, other.data.data); + } else { + // highly unlikely, but possible case: type has changed relocatability + // between builds + d.data.shared = QVariant::PrivateShared::create(iface->size, iface->alignment); + QtMetaTypePrivate::copyConstruct(iface, d.data.shared->data(), other.data.data); + } - // if not trivially copyable, ask to copy - if (iface->copyCtr) - QtMetaTypePrivate::copyConstruct(iface, d.data.data, other.data.data); } return d; } diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 6181f3d97ab..266c149d1d1 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -124,9 +124,8 @@ public: const void *storage() const { return is_shared ? data.shared->data() : &data.data; } - // determine internal storage at compile time template const T &get() const - { return *static_cast(CanUseInternalSpace ? &data.data : data.shared->data()); } + { return *static_cast(storage()); } inline const QtPrivate::QMetaTypeInterface *typeInterface() const { @@ -771,7 +770,7 @@ template inline T qvariant_cast(QVariant &&v) { QMetaType targetType = QMetaType::fromType(); if (v.d.type() == targetType) { - if constexpr (QVariant::Private::CanUseInternalSpace) { + if (!v.d.is_shared) { return std::move(*reinterpret_cast(v.d.data.data)); } else { if (v.d.data.shared->ref.loadRelaxed() == 1)