From 95f8cd5632dcb72ec4fa7910099f210ce5f22078 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Mon, 28 Sep 2020 11:15:27 +0200 Subject: qqmlimport: Use stable_partition instead of stable_sort We do not actually need to sort the imports list, we just require that all inline component imports come before all other imports. This avoids triggering a MSVC STL debug assertion about the used Compare function not actually creating a strict ordering. Fixes: QTBUG-86989 Change-Id: I381852392545287ec02b186fcb4f33be3ae95b33 Reviewed-by: Ulf Hermann (cherry picked from commit 3eb9ee34c06d54ea21fedd3188c60e536a487b1c) Reviewed-by: Qt Cherry-pick Bot --- src/qml/qml/qqmlimport.cpp | 4 +-- .../qml/qqmllanguage/data/twoInlineComponents.qml | 6 +++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 30 +++++++++++++--------- 3 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 tests/auto/qml/qqmllanguage/data/twoInlineComponents.qml diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index c3f6a9057d..6d4fba0aa4 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -989,8 +989,8 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS typeRecursionDetected = &localTypeRecursionDetected; if (needsSorting()) { - std::stable_sort(imports.begin(), imports.end(), [](QQmlImportInstance *left, QQmlImportInstance *) { - return left->isInlineComponent; + std::stable_partition(imports.begin(), imports.end(), [](QQmlImportInstance *import) { + return import->isInlineComponent; }); setNeedsSorting(false); } diff --git a/tests/auto/qml/qqmllanguage/data/twoInlineComponents.qml b/tests/auto/qml/qqmllanguage/data/twoInlineComponents.qml new file mode 100644 index 0000000000..73cb4cb5b0 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/twoInlineComponents.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Item { + component IC1: Item {} + component IC2: Item {} +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 187243fbbd..e32fa884a2 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -5557,6 +5557,7 @@ void tst_qqmllanguage::inlineComponent() QFETCH(QUrl, componentUrl); QFETCH(QColor, color); QFETCH(int, width); + QFETCH(bool, checkProperties); QQmlEngine engine; QQmlComponent component(&engine, componentUrl); QScopedPointer o(component.create()); @@ -5564,10 +5565,12 @@ void tst_qqmllanguage::inlineComponent() qDebug() << component.errorString(); } QVERIFY(!o.isNull()); - auto icInstance = o->findChild("icInstance"); - QVERIFY(icInstance); - QCOMPARE(icInstance->property("color").value(),color); - QCOMPARE(icInstance->property("width").value(), width); + if (checkProperties) { + auto icInstance = o->findChild("icInstance"); + QVERIFY(icInstance); + QCOMPARE(icInstance->property("color").value(),color); + QCOMPARE(icInstance->property("width").value(), width); + } } void tst_qqmllanguage::inlineComponent_data() @@ -5575,18 +5578,21 @@ void tst_qqmllanguage::inlineComponent_data() QTest::addColumn("componentUrl"); QTest::addColumn("color"); QTest::addColumn("width"); + QTest::addColumn("checkProperties"); + + QTest::newRow("Usage from other component") << testFileUrl("inlineComponentUser1.qml") << QColorConstants::Blue << 24 << true; + QTest::newRow("Reexport") << testFileUrl("inlineComponentUser2.qml") << QColorConstants::Svg::green << 24 << true; + QTest::newRow("Usage in same component") << testFileUrl("inlineComponentUser3.qml") << QColorConstants::Blue << 24 << true; - QTest::newRow("Usage from other component") << testFileUrl("inlineComponentUser1.qml") << QColorConstants::Blue << 24; - QTest::newRow("Reexport") << testFileUrl("inlineComponentUser2.qml") << QColorConstants::Svg::green << 24; - QTest::newRow("Usage in same component") << testFileUrl("inlineComponentUser3.qml") << QColorConstants::Blue << 24; + QTest::newRow("Resolution happens at instantiation") << testFileUrl("inlineComponentUser4.qml") << QColorConstants::Blue << 24 << true; + QTest::newRow("Non-toplevel IC is found") << testFileUrl("inlineComponentUser5.qml") << QColorConstants::Svg::red << 24 << true; - QTest::newRow("Resolution happens at instantiation") << testFileUrl("inlineComponentUser4.qml") << QColorConstants::Blue << 24; - QTest::newRow("Non-toplevel IC is found") << testFileUrl("inlineComponentUser5.qml") << QColorConstants::Svg::red << 24; + QTest::newRow("Resolved in correct order") << testFileUrl("inlineComponentOrder.qml") << QColorConstants::Blue << 200 << true; - QTest::newRow("Resolved in correct order") << testFileUrl("inlineComponentOrder.qml") << QColorConstants::Blue << 200; + QTest::newRow("ID resolves correctly") << testFileUrl("inlineComponentWithId.qml") << QColorConstants::Svg::red << 42 << true; + QTest::newRow("Alias resolves correctly") << testFileUrl("inlineComponentWithAlias.qml") << QColorConstants::Svg::lime << 42 << true; - QTest::newRow("ID resolves correctly") << testFileUrl("inlineComponentWithId.qml") << QColorConstants::Svg::red << 42; - QTest::newRow("Alias resolves correctly") << testFileUrl("inlineComponentWithAlias.qml") << QColorConstants::Svg::lime << 42; + QTest::newRow("Two inline components in same do not crash (QTBUG-86989)") << testFileUrl("twoInlineComponents.qml") << QColor() << 0 << false; } void tst_qqmllanguage::inlineComponentReferenceCycle_data() -- cgit v1.2.3