diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-07-03 01:00:30 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-07-03 06:12:36 +0000 |
commit | 47b2cde5dcca49a1969a43b294931323eff68f74 (patch) | |
tree | 62ff6e849ea545769c8e5f245eaa34531760a1a2 | |
parent | 71d4a62661f771f1ac900fab02840f7863a0deed (diff) | |
parent | 97aa001da97ee8531b3de4bd97496478b2f3f2e9 (diff) |
Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"
11 files changed, 103 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 18105aa75f..e45515fbcf 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1384,7 +1384,8 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru QQmlPropertyData::DontRemoveBinding); if (!b->isValueTypeProxy()) { QQmlBinding *binding = static_cast<QQmlBinding*>(b.data()); - if (!binding->hasError() && !binding->hasDependencies()) + if (!binding->hasError() && !binding->hasDependencies() + && binding->context() && !binding->context()->unresolvedNames) b->removeFromObject(); } diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 63bc64d5e6..af328fbe2a 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -2656,10 +2656,10 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index) model->m_cacheMetaType->initializePrototype(); QV4::ExecutionEngine *v4 = model->m_cacheMetaType->v4Engine; QV4::Scope scope(v4); + ++cacheItem->scriptRef; QV4::ScopedObject o(scope, v4->memoryManager->allocate<QQmlDelegateModelItemObject>(cacheItem)); QV4::ScopedObject p(scope, model->m_cacheMetaType->modelItemProto.value()); o->setPrototypeOf(p); - ++cacheItem->scriptRef; return QQmlV4Handle(o); } diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 771228914b..f618bcf1c3 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -75,6 +75,7 @@ #include <QtCore/qlist.h> #include <QtCore/qdebug.h> #include <QtCore/qelapsedtimer.h> +#include <QtCore/qpointer.h> #if QT_CONFIG(quick_shadereffect) #include <QtQuick/private/qquickshadereffectsource_p.h> @@ -682,12 +683,12 @@ public: : leftSet(false), rightSet(false), upSet(false), downSet(false), tabSet(false), backtabSet(false) {} - QQuickItem *left = nullptr; - QQuickItem *right = nullptr; - QQuickItem *up = nullptr; - QQuickItem *down = nullptr; - QQuickItem *tab = nullptr; - QQuickItem *backtab = nullptr; + QPointer<QQuickItem> left; + QPointer<QQuickItem> right; + QPointer<QQuickItem> up; + QPointer<QQuickItem> down; + QPointer<QQuickItem> tab; + QPointer<QQuickItem> backtab; bool leftSet : 1; bool rightSet : 1; bool upSet : 1; diff --git a/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/Animal.qml b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/Animal.qml new file mode 100644 index 0000000000..5bd7788a8c --- /dev/null +++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/Animal.qml @@ -0,0 +1,15 @@ +pragma Singleton +import QtQml 2.0 + +QtObject { + property string name + property string category + property string sound + property int size: Animal.SizeSmall + + enum SizeType { + SizeSmall, + SizeMedium, + SizeLarge + } +} diff --git a/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/qmldir b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/qmldir new file mode 100644 index 0000000000..f08b348efa --- /dev/null +++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeWithEnum/qmldir @@ -0,0 +1,3 @@ +module dumper.CompositeWithEnum +singleton Animal 1.0 Animal.qml +depends QtQml 2.0 diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp index 17766a89b5..72356a4d84 100644 --- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp +++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp @@ -46,6 +46,7 @@ private slots: void builtins(); void singleton(); void compositeWithinSingleton(); + void compositeWithEnum(); void plugin_data(); void plugin(); @@ -135,6 +136,21 @@ void tst_qmlplugindump::compositeWithinSingleton() QVERIFY2(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")), qPrintable(result)); } +void tst_qmlplugindump::compositeWithEnum() +{ + QProcess dumper; + QStringList args; + args << QLatin1String("dumper.CompositeWithEnum") << QLatin1String("1.0") + << QLatin1String(QT_QMLTEST_DIR "/data"); + dumper.start(qmlplugindumpPath, args); + QVERIFY2(dumper.waitForStarted(), qPrintable(dumper.errorString())); + QVERIFY2(dumper.waitForFinished(), qPrintable(dumper.errorString())); + + const QString &result = dumper.readAllStandardOutput(); + QVERIFY2(result.contains(QLatin1String("exports: [\"Animal 1.0\"]")), qPrintable(result)); + QVERIFY2(result.contains(QLatin1String("Enum {")), qPrintable(result)); +} + void tst_qmlplugindump::plugin_data() { QTest::addColumn<QString>("import"); diff --git a/tests/auto/qml/qqmlecmascript/data/preserveBindingWithUnresolvedNames.qml b/tests/auto/qml/qqmlecmascript/data/preserveBindingWithUnresolvedNames.qml new file mode 100644 index 0000000000..a57bafb07b --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/preserveBindingWithUnresolvedNames.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + property string testTypeOf: typeof(contextProp) +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 59dc5debb9..d06243897c 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -356,6 +356,7 @@ private slots: void callPropertyOnUndefined(); void jumpStrictNotEqualUndefined(); void removeBindingsWithNoDependencies(); + void preserveBindingWithUnresolvedNames(); void temporaryDeadZone(); void importLexicalVariables_data(); void importLexicalVariables(); @@ -8822,6 +8823,18 @@ void tst_qqmlecmascript::removeBindingsWithNoDependencies() } +void tst_qqmlecmascript::preserveBindingWithUnresolvedNames() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("preserveBindingWithUnresolvedNames.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + QCOMPARE(object->property("testTypeOf").toString(), QString("undefined")); + QObject obj; + engine.rootContext()->setContextProperty("contextProp", &obj); + QCOMPARE(object->property("testTypeOf").toString(), QString("object")); +} + void tst_qqmlecmascript::temporaryDeadZone() { QJSEngine engine; diff --git a/tests/auto/quick/qquickitem2/data/keynavigationtest_implicitDestroy.qml b/tests/auto/quick/qquickitem2/data/keynavigationtest_implicitDestroy.qml new file mode 100644 index 0000000000..54d20273da --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/keynavigationtest_implicitDestroy.qml @@ -0,0 +1,13 @@ +import QtQuick 2.12 + +Item { + id: root + + function createImplicitKeyNavigation() { + var item = Qt.createQmlObject("import QtQuick 2.0; Item { }", root); + item.KeyNavigation.up = root + item.destroy(); + + forceActiveFocus(); + } +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 7107f4d995..399535cfa6 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -86,6 +86,7 @@ private slots: void keyNavigation_RightToLeft(); void keyNavigation_skipNotVisible(); void keyNavigation_implicitSetting(); + void keyNavigation_implicitDestroy(); void keyNavigation_focusReason(); void keyNavigation_loop(); void layoutMirroring(); @@ -2164,6 +2165,29 @@ void tst_QQuickItem::keyNavigation_implicitSetting() delete window; } +// QTBUG-75399 +void tst_QQuickItem::keyNavigation_implicitDestroy() +{ + QQuickView view; + view.setSource(testFileUrl("keynavigationtest_implicitDestroy.qml")); + view.show(); + + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickItem *root = view.rootObject(); + QVERIFY(QMetaObject::invokeMethod(root, "createImplicitKeyNavigation")); + + // process events is necessary to trigger upcoming memory access violation + QTest::qWait(0); + + QVERIFY(root->hasActiveFocus()); + + QKeyEvent keyPress = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(&view, &keyPress); // <-- access violation happens here + // this should fail the test, even if the access violation does not occur + QVERIFY(!keyPress.isAccepted()); +} + void tst_QQuickItem::keyNavigation_focusReason() { QQuickView *window = new QQuickView(nullptr); diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index f3b931fbbf..0a66aa419b 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -479,8 +479,12 @@ public: } } - for (const QMetaObject *meta : qAsConst(objectsToMerge)) + for (const QMetaObject *meta : qAsConst(objectsToMerge)) { + for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index) + dump(meta->enumerator(index)); + writeMetaContent(meta, &knownAttributes); + } qml->writeEndObject(); } |