aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp8
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp7
-rw-r--r--src/qmlcompiler/qqmljstyperesolver.cpp4
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt1
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/voidConversion.qml10
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp18
-rw-r--r--tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml1
7 files changed, 42 insertions, 7 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index 64021893ed..ccb84ad0b6 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -3338,10 +3338,14 @@ QString QQmlJSCodeGenerator::convertStored(
return u"std::numeric_limits<double>::quiet_NaN()"_s;
if (m_typeResolver->equals(to, m_typeResolver->stringType()))
return QQmlJSUtils::toLiteral(u"undefined"_s);
+ if (m_typeResolver->equals(to, m_typeResolver->varType()))
+ return u"QVariant()"_s;
+ if (m_typeResolver->equals(to, m_typeResolver->jsValueType()))
+ return u"QJSValue();"_s;
+ if (m_typeResolver->equals(to, m_typeResolver->jsPrimitiveType()))
+ return u"QJSPrimitiveValue()"_s;
if (m_typeResolver->equals(from, to))
return QString();
- // Anything else is just the default constructed type.
- return to->augmentedInternalName() + u"()"_s;
}
if (m_typeResolver->equals(from, m_typeResolver->nullType())) {
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp
index a8d397d859..9fd1dfc77e 100644
--- a/src/qmlcompiler/qqmljstypepropagator.cpp
+++ b/src/qmlcompiler/qqmljstypepropagator.cpp
@@ -83,9 +83,10 @@ void QQmlJSTypePropagator::generate_Ret()
if (m_function->isSignalHandler) {
// Signal handlers cannot return anything.
- } else if (!m_returnType.isValid() && m_state.accumulatorIn().isValid()
- && !m_typeResolver->registerContains(
- m_state.accumulatorIn(), m_typeResolver->voidType())) {
+ } else if (m_typeResolver->registerContains(
+ m_state.accumulatorIn(), m_typeResolver->voidType())) {
+ // You can always return undefined.
+ } else if (!m_returnType.isValid() && m_state.accumulatorIn().isValid()) {
setError(u"function without return type annotation returns %1"_s
.arg(m_state.accumulatorIn().descriptiveName()));
diff --git a/src/qmlcompiler/qqmljstyperesolver.cpp b/src/qmlcompiler/qqmljstyperesolver.cpp
index f67d3b3ac6..49d328472c 100644
--- a/src/qmlcompiler/qqmljstyperesolver.cpp
+++ b/src/qmlcompiler/qqmljstyperesolver.cpp
@@ -1192,11 +1192,11 @@ bool QQmlJSTypeResolver::canPrimitivelyConvertFromTo(
return true;
}
- if (equals(from, m_voidType) || equals(to, m_voidType))
+ if (equals(to, m_voidType))
return true;
if (to.isNull())
- return false;
+ return equals(from, m_voidType);
const auto types = { m_dateTimeType, m_dateType, m_timeType, m_stringType };
for (const auto &originType : types) {
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index 798c513338..99cbf9dcd5 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -245,6 +245,7 @@ set(qml_files
variantReturn.qml
variantlist.qml
versionmismatch.qml
+ voidConversion.qml
voidfunction.qml
dummy_imports.qml
)
diff --git a/tests/auto/qml/qmlcppcodegen/data/voidConversion.qml b/tests/auto/qml/qmlcppcodegen/data/voidConversion.qml
new file mode 100644
index 0000000000..f5826d9e48
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/voidConversion.qml
@@ -0,0 +1,10 @@
+import QtQml
+
+QtObject {
+ id: item
+ property point p: Qt.point(20, 10)
+
+ Component.onCompleted: {
+ item.p = undefined
+ }
+}
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index ec5f400fe2..881253f3ea 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -206,6 +206,7 @@ private slots:
void variantMapLookup();
void variantReturn();
void variantlist();
+ void voidConversion();
void voidFunction();
};
@@ -4189,6 +4190,23 @@ void tst_QmlCppCodegen::variantlist()
QCOMPARE(things[1].toInt(), 30);
}
+void tst_QmlCppCodegen::voidConversion()
+{
+ QQmlEngine engine;
+ const QUrl url(u"qrc:/qt/qml/TestTypes/voidConversion.qml"_s);
+ QQmlComponent c(&engine, url);
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(url.toString() + u":8: Error: Cannot assign [undefined] to QPointF"_s));
+
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(o);
+
+ QCOMPARE(o->property("p"), QPointF(20, 10));
+}
+
void tst_QmlCppCodegen::voidFunction()
{
QQmlEngine engine;
diff --git a/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml b/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml
index 2a51cceac3..b6c0f59c7f 100644
--- a/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml
+++ b/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml
@@ -5,5 +5,6 @@ Item {
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
anchors.baseline: undefined
+ Component.onCompleted: anchors.bottom = undefined
}
}