aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2024-05-22 16:33:47 +0200
committerUlf Hermann <[email protected]>2024-05-25 08:11:24 +0200
commited61e7c6d2ae80935b02c6eedc293e3b875520d7 (patch)
treef1f39767b7c97608a45f42192e0efb475dd6fb20
parent7bdeea2c309150c8b49558b135232926d6a89c50 (diff)
QmlCompiler: Explicitly cast operations that result in QString
We may be using QStringBuilder, and that can be stored in QVariant (and possibly other places). Fixes: QTBUG-125576 Change-Id: Ib31e31591a3333e51f1d5594ee05fdb8f0744714 Reviewed-by: Fabian Kosmale <[email protected]>
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp6
-rw-r--r--tests/auto/qml/qmlcppcodegen/CMakeLists.txt4
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt29
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/writableVariantMap.h31
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/writeVariantMap.qml10
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp17
6 files changed, 95 insertions, 2 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index 9f609f39fb..1ef9194bdb 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -3639,9 +3639,13 @@ void QQmlJSCodeGenerator::generateArithmeticOperation(
const QQmlJSRegisterContent originalOut = m_typeResolver->original(m_state.accumulatorOut());
m_body += m_state.accumulatorVariableOut;
m_body += u" = "_s;
+ const QString explicitCast
+ = m_typeResolver->equals(originalOut.storedType(), m_typeResolver->stringType())
+ ? originalOut.storedType()->internalName()
+ : QString();
m_body += conversion(
originalOut, m_state.accumulatorOut(),
- u'(' + lhs + u' ' + cppOperator + u' ' + rhs + u')');
+ explicitCast + u'(' + lhs + u' ' + cppOperator + u' ' + rhs + u')');
m_body += u";\n"_s;
}
diff --git a/tests/auto/qml/qmlcppcodegen/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/CMakeLists.txt
index 42ad6d23d6..715ad6162a 100644
--- a/tests/auto/qml/qmlcppcodegen/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/CMakeLists.txt
@@ -19,6 +19,8 @@ qt_internal_add_test(tst_qmlcppcodegen
codegen_test_moduleplugin
codegen_test_hidden
codegen_test_hiddenplugin
+ codegen_test_stringbuilder
+ codegen_test_stringbuilderplugin
)
qt_internal_add_test(tst_qmlcppcodegen_interpreted
@@ -31,6 +33,8 @@ qt_internal_add_test(tst_qmlcppcodegen_interpreted
codegen_test_moduleplugin
codegen_test_hidden
codegen_test_hiddenplugin
+ codegen_test_stringbuilder
+ codegen_test_stringbuilderplugin
DEFINES
QT_TEST_FORCE_INTERPRETER
)
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index 8c5449d192..7f2e6ad967 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -346,6 +346,33 @@ add_dependencies(codegen_test_hidden Qt::Quick)
qt_autogen_tools_initial_setup(codegen_test_hiddenplugin)
+qt_policy(SET QTP0004 NEW)
+
+qt_add_library(codegen_test_stringbuilder STATIC)
+qt_autogen_tools_initial_setup(codegen_test_stringbuilder)
+
+set_target_properties(codegen_test_stringbuilder PROPERTIES
+ # We really want qmlcachegen here, even if qmlsc is available
+ QT_QMLCACHEGEN_EXECUTABLE qmlcachegen
+ QT_QMLCACHEGEN_ARGUMENTS --validate-basic-blocks
+)
+
+target_compile_definitions(codegen_test_stringbuilder PRIVATE
+ -DGENERATED_CPP_FOLDER="${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache"
+ QT_USE_QSTRINGBUILDER
+)
+
+qt6_add_qml_module(codegen_test_stringbuilder
+ URI StringBuilderTestTypes
+ SOURCES
+ writableVariantMap.h
+ QML_FILES
+ writeVariantMap.qml
+ OUTPUT_DIRECTORY stringbuilderTestTypes
+ __QT_INTERNAL_DISAMBIGUATE_QMLDIR_RESOURCE
+)
+
+qt_autogen_tools_initial_setup(codegen_test_stringbuilderplugin)
qt_add_library(codegen_test_module STATIC)
qt_autogen_tools_initial_setup(codegen_test_module)
@@ -356,7 +383,7 @@ set_target_properties(codegen_test_module PROPERTIES
QT_QMLCACHEGEN_ARGUMENTS --validate-basic-blocks
)
-qt_policy(SET QTP0004 NEW)
+
target_compile_definitions(codegen_test_module PUBLIC
-DGENERATED_CPP_FOLDER="${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache"
diff --git a/tests/auto/qml/qmlcppcodegen/data/writableVariantMap.h b/tests/auto/qml/qmlcppcodegen/data/writableVariantMap.h
new file mode 100644
index 0000000000..3c0fedd28b
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/writableVariantMap.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <QObject>
+#include <QVariantMap>
+#include <QtQml/qqmlregistration.h>
+
+class WritableVariantMap : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(QVariantMap data READ data WRITE setData NOTIFY dataChanged)
+
+public:
+ WritableVariantMap(QObject *parent = nullptr) : QObject(parent) { }
+
+ QVariantMap data() const { return m_data; }
+ void setData(const QVariantMap &data)
+ {
+ if (m_data != data) {
+ m_data = data;
+ emit dataChanged();
+ }
+ }
+
+signals:
+ void dataChanged();
+
+private:
+ QVariantMap m_data;
+};
+
+
diff --git a/tests/auto/qml/qmlcppcodegen/data/writeVariantMap.qml b/tests/auto/qml/qmlcppcodegen/data/writeVariantMap.qml
new file mode 100644
index 0000000000..536e53b408
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/writeVariantMap.qml
@@ -0,0 +1,10 @@
+pragma Strict
+import StringBuilderTestTypes
+
+WritableVariantMap {
+ id: dragSource
+ property string modelData: "Drag Me"
+ data: ({
+ "text/plain": "%" + dragSource.modelData + "%"
+ })
+}
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index 9b66143f62..53cc068e8c 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -256,6 +256,7 @@ private slots:
void voidConversion();
void voidFunction();
void writeBack();
+ void writeVariantMap();
};
static QByteArray arg1()
@@ -5107,6 +5108,22 @@ void tst_QmlCppCodegen::writeBack()
QCOMPARE(person->property("ints"), QVariant::fromValue(QList<int>({12, 22, 2, 1, 0, 0, 33})));
}
+void tst_QmlCppCodegen::writeVariantMap()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, QUrl(u"qrc:/qt/qml/StringBuilderTestTypes/writeVariantMap.qml"_s));
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ const QVariantMap v = object->property("data").toMap();
+ QCOMPARE(v.size(), 1);
+ const QVariant textPlain = v[u"text/plain"_s];
+ QCOMPARE(textPlain.metaType(), QMetaType::fromType<QString>());
+ QCOMPARE(textPlain.toString(), u"%Drag Me%"_s);
+
+}
+
QTEST_MAIN(tst_QmlCppCodegen)
#include "tst_qmlcppcodegen.moc"