diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-06-09 10:49:03 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-06-10 20:40:57 +0000 |
commit | 9f9743c8b4c0fc7bdd45b4f8f8607735d463a601 (patch) | |
tree | c046d63560f284146b61ea15badd3fe75fb83984 | |
parent | 2b8b69edc13d8abf49b68509b7a379f7ca1b7cb2 (diff) |
QmlCompiler: Don't retrieve metaobjects for value and sequence types
This is not valid QML, and the generated code crashes.
Fixes: QTBUG-104092
Change-Id: If609acc2f2dc84a2e8f7c26d4d1b6c626f337cad
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
(cherry picked from commit 2a4ec96ae00c7372b1827d3872990a47658d6ff5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/qmlcompiler/qqmljstyperesolver.cpp | 23 | ||||
-rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/typePropertyClash.qml | 5 | ||||
-rw-r--r-- | tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp | 12 |
4 files changed, 33 insertions, 8 deletions
diff --git a/src/qmlcompiler/qqmljstyperesolver.cpp b/src/qmlcompiler/qqmljstyperesolver.cpp index 2aebb9c5b8..5c15aba780 100644 --- a/src/qmlcompiler/qqmljstyperesolver.cpp +++ b/src/qmlcompiler/qqmljstyperesolver.cpp @@ -853,14 +853,21 @@ QQmlJSRegisterContent QQmlJSTypeResolver::scopedType(const QQmlJSScope::ConstPtr } } - // A plain reference to a non-singleton, non-attached type. - // If it's undefined, we can actually get an "instance" of it. - // Therefore, use a primitive value to store it. - // Otherwise this is a plain type reference without instance. - // We may still need the plain type reference for enum lookups, - // so store it in QJSValue for now. - return QQmlJSRegisterContent::create(metaObjectType(), metaObjectType(), - QQmlJSRegisterContent::MetaType, type); + switch (type->accessSemantics()) { + case QQmlJSScope::AccessSemantics::None: + case QQmlJSScope::AccessSemantics::Reference: + // A plain reference to a non-singleton, non-attached type. + // We may still need the plain type reference for enum lookups, + // Store it as QMetaObject. + // This only works with namespaces and object types. + return QQmlJSRegisterContent::create(metaObjectType(), metaObjectType(), + QQmlJSRegisterContent::MetaType, type); + case QQmlJSScope::AccessSemantics::Sequence: + case QQmlJSScope::AccessSemantics::Value: + // This is not actually a type reference. You cannot get the metaobject + // of a value type in QML and sequences don't even have metaobjects. + break; + } } if (m_jsGlobalObject->hasProperty(name)) { diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt index 7266ad0b5a..de4b1fc278 100644 --- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt +++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt @@ -133,6 +133,7 @@ set(qml_files text.qml themerbad.qml themergood.qml + typePropertyClash.qml typedArray.qml undefinedResets.qml unknownAttached.qml diff --git a/tests/auto/qml/qmlcppcodegen/data/typePropertyClash.qml b/tests/auto/qml/qmlcppcodegen/data/typePropertyClash.qml new file mode 100644 index 0000000000..34dcb3b9c6 --- /dev/null +++ b/tests/auto/qml/qmlcppcodegen/data/typePropertyClash.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + objectName: 'Size: ' + size +} diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp index 8733bf6b96..9c1f83fa2f 100644 --- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp +++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp @@ -138,6 +138,7 @@ private slots: void valueTypeLists(); void boundComponents(); void invisibleListElementType(); + void typePropertyClash(); }; void tst_QmlCppCodegen::simpleBinding() @@ -2201,6 +2202,17 @@ void tst_QmlCppCodegen::invisibleListElementType() QCOMPARE(ref.size(), 0); } +void tst_QmlCppCodegen::typePropertyClash() +{ + QQmlEngine engine; + engine.rootContext()->setContextProperty(u"size"_s, 5); + QQmlComponent c(&engine, QUrl(u"qrc:/TestTypes/typePropertyClash.qml"_s)); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QCOMPARE(o->objectName(), u"Size: 5"_s); +} + void tst_QmlCppCodegen::runInterpreted() { #ifdef Q_OS_ANDROID |