aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Goldstein <max.goldstein@qt.io>2020-11-18 09:59:12 +0100
committerMaximilian Goldstein <max.goldstein@qt.io>2020-11-18 17:39:05 +0100
commit7f74a613f83f35fc5204857868378ed404628e46 (patch)
tree8b13ace6817f1873227536b677658f1dce0b9608
parent8b109a322313ec6227392135f0e71f11adc64ea9 (diff)
tst_qqmlproperty: Fix interfaceBinding crash on MSVC 2019
Change-Id: I4bb4a66b7ccca838e058962bbc297659b273c78e Done-with: Fabian Kosmale <fabian.kosmale@qt.io> Fixes: QTBUG-84416 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/qml/qqmlproperty.cpp8
-rw-r--r--tests/auto/qml/qqmlproperty/interfaces.h16
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp17
3 files changed, 31 insertions, 10 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 8ffdf1738c..68127f8686 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1417,10 +1417,14 @@ bool QQmlPropertyPrivate::write(
if (!ok && QQmlMetaType::isInterface(propertyType)) {
auto valueAsQObject = qvariant_cast<QObject *>(value);
- if (valueAsQObject && valueAsQObject->qt_metacast(QQmlMetaType::interfaceIId(propertyType))) {
+
+ if (void *interface = valueAsQObject
+ ? valueAsQObject->qt_metacast(QQmlMetaType::interfaceIId(propertyType))
+ : nullptr;
+ interface) {
// this case can occur when object has an interface type
// and the variant contains a type implementing the interface
- return property.writeProperty(object, const_cast<void *>(value.constData()), flags);
+ return property.writeProperty(object, &interface, flags);
}
}
diff --git a/tests/auto/qml/qqmlproperty/interfaces.h b/tests/auto/qml/qqmlproperty/interfaces.h
index 2c06c5f594..f89b47efbe 100644
--- a/tests/auto/qml/qqmlproperty/interfaces.h
+++ b/tests/auto/qml/qqmlproperty/interfaces.h
@@ -30,8 +30,11 @@
#define INTERFACES_H
#include <QtQml/qqml.h>
+#include <QTest>
struct Interface {
+ // non-virtual, non-QObject interfaces are not supported
+ virtual ~Interface() {};
};
QT_BEGIN_NAMESPACE
@@ -39,7 +42,7 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(Interface, MyInterface_iid);
QT_END_NAMESPACE
-class A : public QObject, Interface {
+class A : public QObject, public Interface {
Q_OBJECT
Q_INTERFACES(Interface)
};
@@ -57,6 +60,9 @@ struct Interface2
{
Q_GADGET
QML_INTERFACE
+public:
+ // non-virtual, non-QObject interfaces are not supported
+ virtual ~Interface2() {};
};
QT_BEGIN_NAMESPACE
@@ -64,7 +70,8 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(Interface2, MyInterface2_iid);
QT_END_NAMESPACE
-class A2 : public QObject, Interface2 {
+class A2 : public QObject, public Interface2
+{
Q_OBJECT
QML_ELEMENT
Q_INTERFACES(Interface2)
@@ -94,7 +101,8 @@ public:
}
void setInterface(Interface* interface)
{
- QObject* object = reinterpret_cast<QObject*>(interface);
+ QObject* object = dynamic_cast<A*>(interface); // we know that we only get an A
+ QVERIFY(object);
m_testValue = object->property("i").toInt();
emit testValueChanged();
if (m_interface == interface)
@@ -135,7 +143,7 @@ public:
}
void setInterface(Interface2* interface2)
{
- QObject* object = reinterpret_cast<QObject*>(interface2);
+ QObject* object = dynamic_cast<QObject*>(interface2);
m_testValue = object->property("i").toInt();
emit testValueChanged();
if (m_interface == interface2)
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 1fd0b1a7d1..10a4881579 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -2146,15 +2146,23 @@ void tst_qqmlproperty::nullPropertyBinding()
void tst_qqmlproperty::interfaceBinding()
{
-#if defined(Q_CC_MSVC)
- QSKIP("Test disabled due to crashing. See QTBUG-84416");
-#endif
qmlRegisterInterface<Interface>("Interface", 1);
qmlRegisterType<A>("io.qt.bugreports", 1, 0, "A");
qmlRegisterType<B>("io.qt.bugreports", 1, 0, "B");
qmlRegisterType<C>("io.qt.bugreports", 1, 0, "C");
qmlRegisterType<InterfaceConsumer>("io.qt.bugreports", 1, 0, "InterfaceConsumer");
+ // Currently registration macros such as QML_ELEMENT are broken when there's multiple inheritance (QTBUG-88623)
+ // So these types have to be registered again.
+ // TODO: Fix QTBUG-88623 and remove this hack
+ qmlRegisterInterface<Interface2>("Interface2", 2);
+ qmlRegisterType<A2>("io.qt.bugreports", 2, 0, "A2");
+ qmlRegisterType<A2>("io.qt.bugreports", 2, 0, "A2");
+ qmlRegisterType<B2>("io.qt.bugreports", 2, 0, "B2");
+ qmlRegisterType<C2>("io.qt.bugreports", 2, 0, "C2");
+ qmlRegisterType<InterfaceConsumer2>("io.qt.bugreports", 2, 0, "InterfaceConsumer2");
+
+
const QVector<QUrl> urls = {
testFileUrl("interfaceBinding.qml"),
testFileUrl("interfaceBinding2.qml")
@@ -2164,7 +2172,8 @@ void tst_qqmlproperty::interfaceBinding()
QQmlEngine engine;
QQmlComponent component(&engine, url);
QScopedPointer<QObject> root(component.create());
- QVERIFY(root);
+ QVERIFY2(root, qPrintable(component.errorString()));
+
QCOMPARE(root->findChild<QObject*>("a1")->property("testValue").toInt(), 42);
QCOMPARE(root->findChild<QObject*>("a2")->property("testValue").toInt(), 43);
QCOMPARE(root->findChild<QObject*>("a3")->property("testValue").toInt(), 44);