diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2025-06-20 11:57:49 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2025-06-23 15:44:38 +0200 |
| commit | 32602bef7c40261cbe61d72e8cf043feb3734d3e (patch) | |
| tree | 08b937c68891fcfff999ebd939feedb71699e27b /tests/auto/qml/qmlcppcodegen | |
| parent | 9035d1cb2a474a6df52ca395e6c185964ec94de0 (diff) | |
QmlCompiler: Sharpen side effect detection
Stack-created lists of primitives or pointers cannot be affected by side
effects. We cannot write a value affected by side effects to a list that
isn't, though.
Pick-to: 6.10 6.9 6.8 6.5
Task-number: QTBUG-137540
Change-Id: I99ab4337cabc6111a81b8164fd94962edc0db25e
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Diffstat (limited to 'tests/auto/qml/qmlcppcodegen')
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/Categorizer.qml | 22 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/data/valueTypeLists.qml | 8 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp | 21 |
3 files changed, 50 insertions, 1 deletions
diff --git a/tests/auto/qml/qmlcppcodegen/data/Categorizer.qml b/tests/auto/qml/qmlcppcodegen/data/Categorizer.qml index 10f2857c19..7ced17c37f 100644 --- a/tests/auto/qml/qmlcppcodegen/data/Categorizer.qml +++ b/tests/auto/qml/qmlcppcodegen/data/Categorizer.qml @@ -2,9 +2,31 @@ pragma Strict import QtQml QtObject { + enum Parameters { + Length = 32, + Iterations = 32768, + + Category0 = 0xf0f, + Category1 = 0xf0f0, + Category2 = 0xf0f0f, + Maximum = 0xf0f0f0, + Mask = 0xabcdef + } + property list<double> nnn: { var result = []; result[0] = 10; return result; } + + function randomNumber() : int { + return (Math.random() * Categorizer.Maximum); + } + + property list<double> numbers: { + var result = []; + for (var i = 0; i < Categorizer.Length; ++i) + result[i] = randomNumber(); + return result; + } } diff --git a/tests/auto/qml/qmlcppcodegen/data/valueTypeLists.qml b/tests/auto/qml/qmlcppcodegen/data/valueTypeLists.qml index cf58ae68c5..b2a62012fd 100644 --- a/tests/auto/qml/qmlcppcodegen/data/valueTypeLists.qml +++ b/tests/auto/qml/qmlcppcodegen/data/valueTypeLists.qml @@ -14,4 +14,12 @@ QtObject { property var intOutOfBounds: intList[34] property var charInBounds: charList[3] property var charOutOfBounds: charList[35] + + property rect evilRect: ({x: 12, y: 13, width: 14, height: 15}) + property list<rect> rectList2: { + let a = []; + a[0] = evilRect + evilRect.x = 666 + return a + } } diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp index b322f870fa..5ec98cbdaf 100644 --- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp +++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp @@ -5670,8 +5670,16 @@ void tst_QmlCppCodegen::valueTypeBehavior() void tst_QmlCppCodegen::valueTypeLists() { QQmlEngine engine; - QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/valueTypeLists.qml"_s)); + const QUrl url(u"qrc:/qt/qml/TestTypes/valueTypeLists.qml"_s); + QQmlComponent c(&engine, url); QVERIFY2(c.isReady(), qPrintable(c.errorString())); + + const QString bindingLoop = url.toString() + + uR"(:3:1: QML QObject*: Binding loop detected for property "rectList2": +qrc:/qt/qml/TestTypes/valueTypeLists.qml:19:5)"_s; + for (int i = 0; i < 2; ++i) + QTest::ignoreMessage(QtWarningMsg, qPrintable(bindingLoop)); + QScopedPointer<QObject> o(c.create()); QCOMPARE(qvariant_cast<QRectF>(o->property("rectInBounds")), QRectF(1, 2, 3, 4)); @@ -5689,6 +5697,10 @@ void tst_QmlCppCodegen::valueTypeLists() QCOMPARE(qvariant_cast<QString>(o->property("charInBounds")), QStringLiteral("d")); QVERIFY(o->metaObject()->indexOfProperty("charOutOfBounds") > 0); QVERIFY(!o->property("charOutOfBounds").isValid()); + + const QList<QRectF> rectList = o->property("rectList2").value<QList<QRectF>>(); + QCOMPARE(rectList.length(), 1); + QCOMPARE(rectList[0], QRectF(666, 13, 14, 15)); } void tst_QmlCppCodegen::valueTypeProperty() @@ -5851,6 +5863,13 @@ void tst_QmlCppCodegen::writeAndReturnTempArray() const QVariant nnn = object->property("nnn"); QCOMPARE(nnn.metaType(), QMetaType::fromType<QList<double>>()); QCOMPARE(nnn.value<QList<double>>(), QList<double>{10}); + + const QVariant numbers = object->property("numbers"); + QCOMPARE(numbers.metaType(), QMetaType::fromType<QList<double>>()); + const QList<double> numbersContent = numbers.value<QList<double>>(); + QCOMPARE(numbersContent.length(), 32); + for (double number: std::as_const(numbersContent)) + QVERIFY(number >= 0 && number < double(0xf0f0f0)); } QTEST_MAIN(tst_QmlCppCodegen) |
