summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-08-19 10:21:30 +0200
committerLars Knoll <lars.knoll@qt.io>2020-08-29 21:01:02 +0200
commitf098aee532bcaad7889931a53b9ed65650c42728 (patch)
treebf0f038068590c62abed6cf144117c9985d7ac4f
parent4a1567ab12064174fc09de1f306de19fd19c1f5d (diff)
Fix comparison of QVariants that contain pointers to QObjects
Allow comparing variants of different types, if both types are pointers to related objects. Amends change 4a69cd7f72140c8f4c83f986b3366f7bd9ba69a3 Change-Id: Ib52b17781b0b7f60cfd5da42fce733faacfa0ae8 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/kernel/qvariant.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 4f92a81cf1..0805456e26 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2076,6 +2076,8 @@ bool QVariant::convert(const int type, void *ptr) const
\li If one type is numeric and the other one a QString, Qt will try to
convert the QString to a matching numeric type and if successful compare
those.
+ \i If both variants contain pointers to QObject derived types, QVariant
+ will check whether the types are related and point to the same object.
\endlist
*/
@@ -2097,6 +2099,8 @@ bool QVariant::convert(const int type, void *ptr) const
\li If one type is numeric and the other one a QString, Qt will try to
convert the QString to a matching numeric type and if successful compare
those.
+ \i If both variants contain pointers to QObject derived types, QVariant
+ will check whether the types are related and point to the same object.
\endlist
*/
@@ -2251,6 +2255,23 @@ static bool numericEquals(const QVariant::Private *d1, const QVariant::Private *
return false;
}
+#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());
+ }
+ return false;
+}
+
+static bool pointerEquals(const QVariant::Private *d1, const QVariant::Private *d2)
+{
+ // simply check whether both types point to the same data
+ return d1->get<QObject *>() == d2->get<QObject *>();
+}
+#endif
+
/*!
\internal
*/
@@ -2262,6 +2283,11 @@ bool QVariant::equals(const QVariant &v) const
// try numeric comparisons, with C++ type promotion rules (no conversion)
if (qIsNumericType(metatype.id()) && qIsNumericType(v.d.typeId()))
return numericEquals(&d, &v.d);
+#ifndef QT_BOOTSTRAPPED
+ // if both types are related pointers to QObjects, check if they point to the same object
+ if (canConvertMetaObject(metatype, v.metaType()))
+ return pointerEquals(&d, &v.d);
+#endif
return false;
}