diff options
author | Alan Alpert <aalpert@blackberry.com> | 2013-08-21 13:21:03 -0700 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-22 21:12:58 +0200 |
commit | fac5337abfef36c631fe73152157446aae0ea3ea (patch) | |
tree | a54f9cd915cf480487359ffb7ad86d65f2ddeb5e /tests | |
parent | da91b1c7312379ee18118059ee03faaf147a7d17 (diff) |
Don't crash with deferred properties
There are cases where a qmlExecuteDeferred(o) can be postponed until the
context of o is being destroyed, at which point it's too late to create
an object in that context.
Task-number: QTBUG-33112
Change-Id: I7f981b5e34e3cb8a52c00de4742a7242d7e4df54
Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests')
4 files changed, 49 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/data/deferredPropertiesInDestruction.qml b/tests/auto/qml/qqmlecmascript/data/deferredPropertiesInDestruction.qml new file mode 100644 index 0000000000..d636dffccc --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/deferredPropertiesInDestruction.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 + +MyVeryDeferredObject { + id: root + objectProperty: MyQmlObject { } +} diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index 64aac83c02..919e06d7ee 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -252,6 +252,7 @@ void registerTypes() qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias"); qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObject"); qmlRegisterType<MyDeferredObject>("Qt.test", 1,0, "MyDeferredObject"); + qmlRegisterType<MyVeryDeferredObject>("Qt.test", 1,0, "MyVeryDeferredObject"); qmlRegisterType<MyQmlContainer>("Qt.test", 1,0, "MyQmlContainer"); qmlRegisterExtendedType<MyBaseExtendedObject, BaseExtensionObject>("Qt.test", 1,0, "MyBaseExtendedObject"); qmlRegisterExtendedType<MyExtendedObject, ExtensionObject>("Qt.test", 1,0, "MyExtendedObject"); diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 4d30816b0a..2aa5fce534 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -376,6 +376,34 @@ private: QObject *m_object2; }; +class MyVeryDeferredObject : public QObject +{ + Q_OBJECT + //For inDestruction test + Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty) + Q_CLASSINFO("DeferredPropertyNames", "objectProperty") + +public: + MyVeryDeferredObject() : m_value(0), m_object(0) {} + ~MyVeryDeferredObject() { + qmlExecuteDeferred(this); //Not a realistic case, see QTBUG-33112 to see how this could happen in practice + } + + int value() const { return m_value; } + void setValue(int v) { m_value = v; emit valueChanged(); } + + QObject *objectProperty() const { return m_object; } + void setObjectProperty(QObject *obj) { m_object = obj; } + +signals: + void valueChanged(); + +private: + int m_value; + QObject *m_object; +}; + class MyBaseExtendedObject : public QObject { Q_OBJECT diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 0db8351135..166e6cb83d 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -102,6 +102,7 @@ private slots: void deferredProperties(); void deferredPropertiesErrors(); void deferredPropertiesInComponents(); + void deferredPropertiesInDestruction(); void extensionObjects(); void overrideExtensionProperties(); void attachedProperties(); @@ -924,6 +925,19 @@ void tst_qqmlecmascript::deferredPropertiesInComponents() delete object; } +void tst_qqmlecmascript::deferredPropertiesInDestruction() +{ + //Test that the component does not get created at all if creation is deferred until the containing context is destroyed + //Very specific operation ordering is needed for this to occur, currently accessing object from object destructor. + // + QQmlComponent component(&engine, testFileUrl("deferredPropertiesInDestruction.qml")); + QObject *object = component.create(); + if (!object) + qDebug() << component.errorString(); + QVERIFY(object != 0); + delete object; //QTBUG-33112 was that this used to cause a crash +} + void tst_qqmlecmascript::extensionObjects() { QQmlComponent component(&engine, testFileUrl("extensionObjects.qml")); |