diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index e70f901a09b..a641313c5bc 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -246,7 +246,14 @@ using NonConstMetaTypeInterface = const QMetaTypeInterface; class QMetaTypeInterface { public: - ushort revision; // 0 in Qt 6.0. Can increase if new field are added + + /* Revision: Can increase if new field are added, or if semantics changes + 0: Initial Revision + 1: the meaning of the NeedsDestruction flag changed + */ + static inline constexpr ushort CurrentRevision = 1; + + ushort revision; ushort alignment; uint size; uint flags; @@ -2461,7 +2468,7 @@ struct QMetaTypeInterfaceWrapper using InterfaceType = std::conditional_t; static inline InterfaceType metaType = { - /*.revision=*/ 0, + /*.revision=*/ QMetaTypeInterface::CurrentRevision, /*.alignment=*/ alignof(T), /*.size=*/ sizeof(T), /*.flags=*/ QMetaTypeForType::Flags, diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 3defbc70ef8..e6493948325 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -152,7 +152,12 @@ inline bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noex inline bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept { - return checkMetaTypeFlagOrPointer(iface, iface->dtor, QMetaType::NeedsDestruction); + /* For metatypes of revision 1, the NeedsDestruction was set even for trivially + destructible types, but their dtor pointer would be null. + For that reason, we need the additional check here. + */ + return iface->revision < 1 || + checkMetaTypeFlagOrPointer(iface, iface->dtor, QMetaType::NeedsDestruction); } inline void defaultConstruct(const QtPrivate::QMetaTypeInterface *iface, void *where) diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 28eb45660eb..32dd1685204 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -331,6 +331,7 @@ private slots: void constructFromIncompatibleMetaType_data(); void constructFromIncompatibleMetaType(); + void constructFromQtLT65MetaType(); void copyNonDefaultConstructible(); private: @@ -5636,6 +5637,33 @@ void tst_QVariant::constructFromIncompatibleMetaType() QVERIFY(!QVariant(regular).convert(type)); } +void tst_QVariant::constructFromQtLT65MetaType() +{ + auto qsizeIface = QtPrivate::qMetaTypeInterfaceForType(); + + QtPrivate::QMetaTypeInterface qsize64Iface = { + /*revision*/0, + 8, + 8, + QMetaType::NeedsConstruction | QMetaType::NeedsDestruction, + 0, + qsizeIface->metaObjectFn, + "FakeQSize", + qsizeIface->defaultCtr, + qsizeIface->copyCtr, + qsizeIface->moveCtr, + /*dtor =*/ nullptr, + qsizeIface->equals, + qsizeIface->lessThan, + qsizeIface->debugStream, + qsizeIface->dataStreamOut, + qsizeIface->dataStreamIn, + /*legacyregop =*/ nullptr + }; + QVariant var{ QMetaType(&qsize64Iface) }; + QVERIFY(var.isValid()); +} + void tst_QVariant::copyNonDefaultConstructible() { NonDefaultConstructible ndc(42);