aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp21
-rw-r--r--tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml25
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp54
3 files changed, 90 insertions, 10 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 5e3db1b2bd..b55dbb4d60 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -1055,16 +1055,17 @@ void QQmlJSImportVisitor::checkRequiredProperties()
: u"here"_s;
if (!prevRequiredScope.isNull()) {
- auto sourceScope = prevRequiredScope->baseType();
- suggestion = QQmlJSFixSuggestion{
- "%1:%2:%3: Property marked as required in %4."_L1
- .arg(sourceScope->filePath())
- .arg(sourceScope->sourceLocation().startLine)
- .arg(sourceScope->sourceLocation().startColumn)
- .arg(requiredScopeName),
- sourceScope->sourceLocation()
- };
- suggestion->setFilename(sourceScope->filePath());
+ if (auto sourceScope = prevRequiredScope->baseType()) {
+ suggestion = QQmlJSFixSuggestion{
+ "%1:%2:%3: Property marked as required in %4."_L1
+ .arg(sourceScope->filePath())
+ .arg(sourceScope->sourceLocation().startLine)
+ .arg(sourceScope->sourceLocation().startColumn)
+ .arg(requiredScopeName),
+ sourceScope->sourceLocation()
+ };
+ suggestion->setFilename(sourceScope->filePath());
+ }
} else {
message += " (marked as required by %1)"_L1.arg(requiredScopeName);
}
diff --git a/tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml b/tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml
new file mode 100644
index 0000000000..f435d2ec4a
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml
@@ -0,0 +1,25 @@
+import QtQuick
+
+Item {
+ id: root
+
+ Item {
+ id: inner
+
+ Tumbler {
+ id: year
+
+ delegate: Rectangle {
+ required property var modelData
+ }
+ }
+
+ Tumbler {
+ id: month
+
+ delegate: Rectangle {
+ required property var modelData
+ }
+ }
+ }
+}
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index 653556a213..21e76a4ab5 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -74,6 +74,9 @@ private slots:
void aotstatsGeneration_data();
void aotstatsGeneration();
void aotstatsFormatRevisionMissmatch();
+
+ void crash_data();
+ void crash();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -122,6 +125,36 @@ static bool generateCache(const QString &qmlFileName, QByteArray *capturedStderr
return proc.exitCode() == 0;
}
+static bool generateCpp(const QString &qmlFileName, QByteArray *capturedStderr = nullptr)
+{
+#if defined(QTEST_CROSS_COMPILED)
+ QTest::qFail("You cannot call qmlcachegen on the target.", __FILE__, __LINE__);
+ return false;
+#endif
+ QProcess proc;
+ if (capturedStderr == nullptr)
+ proc.setProcessChannelMode(QProcess::ForwardedChannels);
+ proc.setProgram(QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath)
+ + QLatin1String("/qmlcachegen"));
+ QTemporaryDir outputDir;
+ const QString outputFile = outputDir.filePath("output.cpp"_L1);
+ proc.setArguments(QStringList{ "--resource-path"_L1, "qrc:/qt/qml/Crashes/testFile.qml"_L1,
+ "-o"_L1, outputFile, qmlFileName });
+ proc.start();
+ if (!proc.waitForFinished())
+ return false;
+
+ if (capturedStderr)
+ *capturedStderr = proc.readAllStandardError();
+
+ if (!QFile::exists(outputFile))
+ return false;
+
+ if (proc.exitStatus() != QProcess::NormalExit)
+ return false;
+ return proc.exitCode() == 0;
+}
+
tst_qmlcachegen::tst_qmlcachegen()
: QQmlDataTest(QT_QMLTEST_DATADIR)
{
@@ -1049,6 +1082,27 @@ void tst_qmlcachegen::aotstatsFormatRevisionMissmatch()
QVERIFY(!QQmlJS::AotStats::fromJsonDocument(document).has_value());
}
+void tst_qmlcachegen::crash_data()
+{
+ QTest::addColumn<QString>("fileName");
+
+ QTest::addRow("buggyFixSuggestion") << u"buggyFixSuggestion.qml"_s;
+}
+
+void tst_qmlcachegen::crash()
+{
+#if defined(QTEST_CROSS_COMPILED)
+ QSKIP("Cannot call qmlcachegen on cross-compiled target.");
+#endif
+
+ QFETCH(QString, fileName);
+ const QString filePath = testFile("crashes/" + fileName);
+
+ QFile file(filePath);
+ QVERIFY(file.exists());
+ QVERIFY(generateCpp(filePath));
+}
+
const QQmlScriptString &ScriptStringProps::undef() const
{
return m_undef;