QVariant: don't use the static CanUseInternalSpace with existing objects
It's possible for the QVariant to have been created by an older or newer build of the library in question in which the type in question was relocatable but has ceased to be, or wasn't relocatable but now is. [ChangeLog][QtCore][QVariant] Fixed a bug where QVariant could misbehave regarding types that changed from non-relocatable to relocatable (or vice-versa) and not all uses of it were recompiled. To benefit from this fix, applications must be recompiled, but they will be safe going forward. Pick-to: 6.8 Change-Id: I222806b3804df6272abdfffd45f96312d23be1af Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit eb87b0444ac8fec4d86bc26dc4bec80f82953f7c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
22f33e1bd2
commit
c1bb08ab26
@ -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;
|
||||
}
|
||||
|
@ -124,9 +124,8 @@ public:
|
||||
const void *storage() const
|
||||
{ return is_shared ? data.shared->data() : &data.data; }
|
||||
|
||||
// determine internal storage at compile time
|
||||
template<typename T> const T &get() const
|
||||
{ return *static_cast<const T *>(CanUseInternalSpace<T> ? &data.data : data.shared->data()); }
|
||||
{ return *static_cast<const T *>(storage()); }
|
||||
|
||||
inline const QtPrivate::QMetaTypeInterface *typeInterface() const
|
||||
{
|
||||
@ -771,7 +770,7 @@ template<typename T> inline T qvariant_cast(QVariant &&v)
|
||||
{
|
||||
QMetaType targetType = QMetaType::fromType<T>();
|
||||
if (v.d.type() == targetType) {
|
||||
if constexpr (QVariant::Private::CanUseInternalSpace<T>) {
|
||||
if (!v.d.is_shared) {
|
||||
return std::move(*reinterpret_cast<T *>(v.d.data.data));
|
||||
} else {
|
||||
if (v.d.data.shared->ref.loadRelaxed() == 1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user