diff options
| author | Ulf Hermann <[email protected]> | 2024-05-22 16:33:47 +0200 |
|---|---|---|
| committer | Ulf Hermann <[email protected]> | 2024-05-25 08:11:24 +0200 |
| commit | ed61e7c6d2ae80935b02c6eedc293e3b875520d7 (patch) | |
| tree | f1f39767b7c97608a45f42192e0efb475dd6fb20 | |
| parent | 7bdeea2c309150c8b49558b135232926d6a89c50 (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.cpp | 6 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt | 29 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/writableVariantMap.h | 31 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/writeVariantMap.qml | 10 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp | 17 |
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" |
