aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-06-16 15:01:00 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-06-17 13:05:24 +0200
commit94063d0c01b1471554773c00c2f6dd4a916fe0ac (patch)
tree1f767eb384312193d805e4e3c8feb6efe37b0be1
parentaa7a10ce8b062bad4df40afc63d2fea34744a2fb (diff)
Fix conversion of entries to be added to QVariantLists
We should pass the variants themselves, not their constData(). Fixes: QTBUG-94502 Change-Id: I92688348d7b46d74935dc11080b26290f5e8be86 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit dbe34dfa0d42510b804c898b77d6fe145473c31b)
-rw-r--r--src/qml/jsruntime/qv4engine.cpp10
-rw-r--r--tests/auto/qml/qqmllanguage/data/variantListConversion.qml7
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp3
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h48
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp19
5 files changed, 83 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 958a994cc3..6883c219bc 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1597,9 +1597,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
continue;
}
}
- asVariant = toVariant(e, arrayValue, valueMetaType, false,
- visitedObjects);
- if (valueMetaType.id() != QMetaType::QVariant) {
+
+ asVariant = toVariant(e, arrayValue, valueMetaType, false, visitedObjects);
+ if (valueMetaType == QMetaType::fromType<QVariant>()) {
+ retnAsIterable.metaContainer().addValue(retn.data(), &asVariant);
+ } else {
auto originalType = asVariant.metaType();
bool couldConvert = asVariant.convert(valueMetaType);
if (!couldConvert) {
@@ -1610,8 +1612,8 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet
// create default constructed value
asVariant = QVariant(valueMetaType, nullptr);
}
+ retnAsIterable.metaContainer().addValue(retn.data(), asVariant.constData());
}
- retnAsIterable.metaContainer().addValue(retn.data(), asVariant.constData());
}
return retn;
}
diff --git a/tests/auto/qml/qqmllanguage/data/variantListConversion.qml b/tests/auto/qml/qqmllanguage/data/variantListConversion.qml
new file mode 100644
index 0000000000..334bf17393
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/variantListConversion.qml
@@ -0,0 +1,7 @@
+import Test
+
+Foo {
+ a.a: 12
+ b.a: 13
+ fooProperty: [a, b]
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 80ec4900c7..fd541fd36a 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -122,6 +122,9 @@ void registerTypes()
qmlRegisterTypesAndRevisions<Extended, Foreign, ForeignExtended>("Test", 1);
qmlRegisterTypesAndRevisions<BareSingleton>("Test", 1);
qmlRegisterTypesAndRevisions<UncreatableSingleton>("Test", 1);
+
+ qmlRegisterTypesAndRevisions<Large>("Test", 1);
+ qmlRegisterTypesAndRevisions<Foo>("Test", 1);
}
QVariant myCustomVariantTypeConverter(const QString &data)
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 25950acb74..2ffc324cae 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -1725,6 +1725,54 @@ public:
Q_INVOKABLE QList<EnumList::Enum> list() const { return { Alpha, Beta, Gamma }; }
};
+struct Large {
+ Q_GADGET
+ QML_VALUE_TYPE(large)
+
+ Q_PROPERTY(uint a MEMBER a)
+ Q_PROPERTY(uint b MEMBER b)
+ Q_PROPERTY(uint c MEMBER c)
+ Q_PROPERTY(uint d MEMBER d)
+ Q_PROPERTY(uint e MEMBER e)
+ Q_PROPERTY(uint f MEMBER f)
+
+public:
+ quint64 a;
+ quint64 b;
+ quint64 c;
+ quint64 d;
+ quint64 e;
+ quint64 f;
+};
+
+inline bool operator==(const Large &a, const Large &b)
+{
+ return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e && a.f == b.f;
+}
+
+inline bool operator!=(const Large &a, const Large &b) { return !(a == b); }
+
+class Foo: public QObject {
+
+ Q_OBJECT
+ Q_PROPERTY(QVariantList fooProperty READ getList WRITE setList)
+ Q_PROPERTY(Large a MEMBER a BINDABLE aBindable)
+ Q_PROPERTY(Large b MEMBER b BINDABLE bBindable)
+ QML_ELEMENT
+
+public:
+ QVariantList getList() const { return mFooProperty;}
+ void setList(QVariantList list) { mFooProperty = list;}
+
+ QBindable<Large> aBindable() { return QBindable<Large>(&a); }
+ QBindable<Large> bBindable() { return QBindable<Large>(&b); }
+
+private:
+ QProperty<Large> a;
+ QProperty<Large> b;
+ QVariantList mFooProperty;
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index f95db6136d..478f236ee2 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -363,6 +363,8 @@ private slots:
void propertyObserverOnReadonly();
+ void variantListConversion();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -6353,6 +6355,23 @@ void tst_qqmllanguage::propertyObserverOnReadonly()
QCOMPARE(o->property("height").toDouble(), 54.2);
}
+void tst_qqmllanguage::variantListConversion()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("variantListConversion.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+
+ Foo *foo = qobject_cast<Foo *>(o.data());
+ QVERIFY(foo);
+ const QVariantList list = foo->getList();
+ QCOMPARE(list.length(), 2);
+ const Large l0 = qvariant_cast<Large>(list.at(0));
+ QCOMPARE(l0.a, 12ull);
+ const Large l1 = qvariant_cast<Large>(list.at(1));
+ QCOMPARE(l1.a, 13ull);
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"