aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-02-25 11:01:17 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-02-25 14:08:22 +0100
commit23ab2e0f5552bb54fef5a6c57f5f82f430d0956c (patch)
treea8bfdf0ea4cc6d1c6caa2da8b8f225185efb5103
parent15ff88f0f16cf5a4a5452e3f8ef93e72cbd66e00 (diff)
QmlCompiler: Correctly label arguments and return types of JS functions
Returning void from any JS function doesn't quite cut it. Pick-to: 6.3 Fixes: QTBUG-101285 Change-Id: I199813627614061ec25139277e8ea23cb844aac5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp8
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt1
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/isnan.qml9
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp22
4 files changed, 38 insertions, 2 deletions
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp
index 949bd0dbc6..e6aec7cc3a 100644
--- a/src/qmlcompiler/qqmljstypepropagator.cpp
+++ b/src/qmlcompiler/qqmljstypepropagator.cpp
@@ -1108,7 +1108,9 @@ void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods,
return;
}
- const auto returnType = match.returnType();
+ const auto returnType = match.isJavaScriptFunction()
+ ? m_typeResolver->jsValueType()
+ : QQmlJSScope::ConstPtr(match.returnType());
setAccumulator(m_typeResolver->globalType(
returnType ? QQmlJSScope::ConstPtr(returnType) : m_typeResolver->voidType()));
if (!m_state.accumulatorOut().isValid())
@@ -1118,7 +1120,9 @@ void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods,
const auto types = match.parameterTypes();
for (int i = 0; i < argc; ++i) {
if (i < types.length()) {
- const QQmlJSScope::ConstPtr type = types.at(i);
+ const QQmlJSScope::ConstPtr type = match.isJavaScriptFunction()
+ ? m_typeResolver->jsValueType()
+ : QQmlJSScope::ConstPtr(types.at(i));
if (!type.isNull()) {
addReadRegister(argv + i, m_typeResolver->globalType(type));
continue;
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index 27156e4055..3e490bc9fc 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -77,6 +77,7 @@ set(qml_files
intOverflow.qml
interactive.qml
interceptor.qml
+ isnan.qml
jsMathObject.qml
jsimport.qml
jsmoduleimport.qml
diff --git a/tests/auto/qml/qmlcppcodegen/data/isnan.qml b/tests/auto/qml/qmlcppcodegen/data/isnan.qml
new file mode 100644
index 0000000000..dfc64e8002
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/isnan.qml
@@ -0,0 +1,9 @@
+import QtQml
+
+QtObject {
+ property real good: 10.1
+ property real bad: "f" / 10
+
+ property bool a: isNaN(good)
+ property bool b: isNaN(bad)
+}
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index bad7271d5a..db30705efc 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -124,6 +124,7 @@ private slots:
void functionLookup();
void objectInVar();
void functionTakingVar();
+ void isnan();
};
void tst_QmlCppCodegen::simpleBinding()
@@ -1847,6 +1848,27 @@ void tst_QmlCppCodegen::functionTakingVar()
QCOMPARE(o->property("c"), QVariant::fromValue<int>(11));
}
+void tst_QmlCppCodegen::isnan()
+{
+ QQmlEngine engine;
+ const QUrl document(u"qrc:/TestTypes/isnan.qml"_qs);
+ QQmlComponent c(&engine, document);
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(o);
+
+ QCOMPARE(o->property("good").toDouble(), 10.1);
+ QVERIFY(qIsNaN(o->property("bad").toDouble()));
+
+ const QVariant a = o->property("a");
+ QCOMPARE(a.metaType(), QMetaType::fromType<bool>());
+ QVERIFY(!a.toBool());
+
+ const QVariant b = o->property("b");
+ QCOMPARE(b.metaType(), QMetaType::fromType<bool>());
+ QVERIFY(b.toBool());
+}
+
void tst_QmlCppCodegen::runInterpreted()
{
if (qEnvironmentVariableIsSet("QV4_FORCE_INTERPRETER"))