summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-07-13 11:48:46 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-08-10 13:21:28 +0000
commit315443d767bd5bd48430dc0c4ef0040238d916e4 (patch)
tree893dd0cacd4ba8e1fa34da832513add94444f376
parent39d9468929f7a267cb897cb173a7a973e90a99a7 (diff)
QVariant: Tolerate QObject* metatypes without QMetaObject
QMetaType does. QVariant should do the same. Change-Id: I3419276b78b3b5ce8bd144dee92685195797d568 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Daniel Nicoletti <daniel.nicoletti@kdab.com> Reviewed-by: Lars Knoll <lars.knoll@qt.io> (cherry picked from commit 6f8ef8c64d4e7af92f585d10a1d5815fcb67831b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/corelib/kernel/qvariant.cpp8
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp48
2 files changed, 53 insertions, 3 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index dcba73731c..8a1197dc5f 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2341,9 +2341,11 @@ static bool numericEquals(const QVariant::Private *d1, const QVariant::Private *
#ifndef QT_BOOTSTRAPPED
static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
{
- if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
- return fromType.metaObject()->inherits(toType.metaObject()) ||
- toType.metaObject()->inherits(fromType.metaObject());
+ if ((fromType.flags() & QMetaType::PointerToQObject)
+ && (toType.flags() & QMetaType::PointerToQObject)) {
+ const QMetaObject *f = fromType.metaObject();
+ const QMetaObject *t = toType.metaObject();
+ return f && t && (f->inherits(t) || t->inherits(f));
}
return false;
}
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 4e5eb430a2..c26f09441b 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -63,6 +63,7 @@
#include "qnumeric.h"
#include <private/qlocale_p.h>
+#include <private/qmetatype_p.h>
#include "tst_qvariant_common.h"
#include <unordered_map>
@@ -309,6 +310,7 @@ private slots:
void mutableView();
void moveOperations();
+ void equalsWithoutMetaObject();
private:
void dataStream_data(QDataStream::Version version);
@@ -5084,5 +5086,51 @@ void tst_QVariant::moveOperations()
QVERIFY(v2.value<std::list<int>>() == list);
}
+class NoMetaObject : public QObject {};
+void tst_QVariant::equalsWithoutMetaObject()
+{
+ using T = NoMetaObject*;
+ QtPrivate::QMetaTypeInterface d = {
+ /*.revision=*/ 0,
+ /*.alignment=*/ alignof(T),
+ /*.size=*/ sizeof(T),
+ /*.flags=*/ QtPrivate::QMetaTypeTypeFlags<T>::Flags,
+ /*.typeId=*/ 0,
+ /*.metaObject=*/ nullptr, // on purpose.
+ /*.name=*/ "NoMetaObject*",
+ /*.defaultCtr=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr) {
+ new (addr) T();
+ },
+ /*.copyCtr=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr, const void *other) {
+ new (addr) T(*reinterpret_cast<const T *>(other));
+ },
+ /*.moveCtr=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr, void *other) {
+ new (addr) T(std::move(*reinterpret_cast<T *>(other)));
+ },
+ /*.dtor=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr) {
+ reinterpret_cast<T *>(addr)->~T();
+ },
+ /*.equals*/ nullptr,
+ /*.lessThan*/ nullptr,
+ /*.debugStream=*/ nullptr,
+ /*.dataStreamOut=*/ nullptr,
+ /*.dataStreamIn=*/ nullptr,
+ /*.legacyRegisterOp=*/ nullptr
+ };
+
+ QMetaType noMetaObjectMetaType(&d);
+ QMetaType qobjectMetaType = QMetaType::fromType<tst_QVariant*>();
+
+ QVERIFY(noMetaObjectMetaType.flags() & QMetaType::PointerToQObject);
+ QVERIFY(qobjectMetaType.flags() & QMetaType::PointerToQObject);
+
+ QVariant noMetaObjectVariant(noMetaObjectMetaType, nullptr);
+ QVariant qobjectVariant(qobjectMetaType, nullptr);
+
+ // Shouldn't crash
+ QVERIFY(noMetaObjectVariant != qobjectVariant);
+ QVERIFY(qobjectVariant != noMetaObjectVariant);
+}
+
QTEST_MAIN(tst_QVariant)
#include "tst_qvariant.moc"