diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-03-15 10:03:02 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-15 16:00:38 +0100 |
commit | af41170bc5e4c1be194bb9bbe883b00c2f7062b7 (patch) | |
tree | 60d7d2a502972ccc96c9cab0893de194a89078dc /tests | |
parent | 3affc261aaa12105dbad60bfa7014126ce4dfcca (diff) |
Fix crash on shutdown with states
When populating deferred properties, we must not set the rootObjectInCreation
flags on the root context and (consequently) on any sub-objects objects created
when initializing deferred properties. Doing so otherwise will end up us
incorrectly linking QQmlContextData together, causing QQmlData::linkedContext
to point to iself and crash on exit upon deletion.
Task-number: QTBUG-37484
Change-Id: Ia5dc92a04e0f66499f15fbac10f14859d387b021
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests')
5 files changed, 56 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmllanguage/data/SubType.qml b/tests/auto/qml/qqmllanguage/data/SubType.qml new file mode 100644 index 0000000000..0698ae2349 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/SubType.qml @@ -0,0 +1,3 @@ +import QtQml 2.0 +QtObject { +} diff --git a/tests/auto/qml/qqmllanguage/data/rootObjectInCreationNotForSubObjects.qml b/tests/auto/qml/qqmllanguage/data/rootObjectInCreationNotForSubObjects.qml new file mode 100644 index 0000000000..afba278ade --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/rootObjectInCreationNotForSubObjects.qml @@ -0,0 +1,7 @@ +import QtQml 2.0 +import Test 1.0 +RootObjectInCreationTester { + subObject: SubType { + property int testValue: 42; + } +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index fad5c1e65d..c37845840b 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -92,6 +92,8 @@ void registerTypes() qmlRegisterType<MyCreateableDerivedClass,1>("Test", 1, 1, "MyCreateableDerivedClass"); qmlRegisterCustomType<CustomBinding>("Test", 1, 0, "CustomBinding", new CustomBindingParser); + + qmlRegisterType<RootObjectInCreationTester>("Test", 1, 0, "RootObjectInCreationTester"); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index a1e2b76bd1..6ed363e363 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1104,6 +1104,23 @@ class CustomBindingParser : public QQmlCustomParser virtual void setCustomData(QObject *object, const QByteArray &data); }; +class RootObjectInCreationTester : public QObject +{ + Q_OBJECT + Q_PROPERTY(QObject *subObject READ subObject WRITE setSubObject FINAL) + Q_CLASSINFO("DeferredPropertyNames", "subObject"); +public: + RootObjectInCreationTester() + : obj(0) + {} + + QObject *subObject() const { return obj; } + void setSubObject(QObject *o) { obj = o; } + +private: + QObject *obj; +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index fa0c393d66..f48e405dff 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -222,6 +222,8 @@ private slots: void preservePropertyCacheOnGroupObjects(); void propertyCacheInSync(); + void rootObjectInCreationNotForSubObjects(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -3624,6 +3626,31 @@ void tst_qqmllanguage::propertyCacheInSync() QCOMPARE(anchors->property("margins").toInt(), 50); } +void tst_qqmllanguage::rootObjectInCreationNotForSubObjects() +{ + QQmlComponent component(&engine, testFile("rootObjectInCreationNotForSubObjects.qml")); + VERIFY_ERRORS(0); + QScopedPointer<QObject> o(component.create()); + QVERIFY(!o.isNull()); + + // QQmlComponent should have set this back to false anyway + QQmlData *ddata = QQmlData::get(o.data()); + QVERIFY(!ddata->rootObjectInCreation); + + QObject *subObject = qvariant_cast<QObject*>(o->property("subObject")); + QVERIFY(!subObject); + + qmlExecuteDeferred(o.data()); + + subObject = qvariant_cast<QObject*>(o->property("subObject")); + QVERIFY(subObject); + + ddata = QQmlData::get(subObject); + // This should never have been set in the first place as there is no + // QQmlComponent to set it back to false. + QVERIFY(!ddata->rootObjectInCreation); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" |