From: Glenn Watson Date: Mon, 21 Nov 2011 22:02:17 +0000 (+1000) Subject: Emit destruction signal before child contexts are destroyed. X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=d2c1adc6f9afc4dd1bab3c487bbde70f3b8f2e81;p=konrad%2Fqtdeclarative.git Emit destruction signal before child contexts are destroyed. Verbatim comment from bug report: When using a QtObject inside an item, and then we call a function in the Component.onDestruction handler of that item, we get a crash. This happens because the QDeclarativeContextData engine has been invalidated before reaching QDeclarativeExpressionPrivate::evalFunction. Change code to emit the onDestruction signal before the child contexts are invalidated. Task-number: QTBUG-22535 Change-Id: Ic4983ae5fdf104ae977189c21dc202c9b02bc2bc Reviewed-by: Chris Adams --- diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 1723603..50e2235 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -529,14 +529,6 @@ QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt) void QDeclarativeContextData::invalidate() { - while (childContexts) { - if (childContexts->ownedByParent) { - childContexts->destroy(); - } else { - childContexts->invalidate(); - } - } - while (componentAttached) { QDeclarativeComponentAttached *a = componentAttached; componentAttached = a->next; @@ -548,6 +540,14 @@ void QDeclarativeContextData::invalidate() emit a->destruction(); } + while (childContexts) { + if (childContexts->ownedByParent) { + childContexts->destroy(); + } else { + childContexts->invalidate(); + } + } + if (prevChild) { *prevChild = nextChild; if (nextChild) nextChild->prevChild = prevChild; diff --git a/tests/auto/declarative/qdeclarativecontext/data/Object_22535.qml b/tests/auto/declarative/qdeclarativecontext/data/Object_22535.qml new file mode 100644 index 0000000..294c744 --- /dev/null +++ b/tests/auto/declarative/qdeclarativecontext/data/Object_22535.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +QtObject { + + function goodBye() + { + } +} diff --git a/tests/auto/declarative/qdeclarativecontext/data/qtbug_22535.qml b/tests/auto/declarative/qdeclarativecontext/data/qtbug_22535.qml new file mode 100644 index 0000000..3553f6c --- /dev/null +++ b/tests/auto/declarative/qdeclarativecontext/data/qtbug_22535.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Rectangle { + width: 64 + height: 64 + + Object_22535 { id:o } + + Component.onDestruction: o.goodBye() +} diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp index 68599a2..ba9db4f 100644 --- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp +++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp @@ -80,6 +80,7 @@ private slots: void refreshExpressionsCrash(); void refreshExpressionsRootContext(); + void qtbug_22535(); private: QDeclarativeEngine engine; }; @@ -644,6 +645,18 @@ void tst_qdeclarativecontext::refreshExpressionsRootContext() delete o1; } +void tst_qdeclarativecontext::qtbug_22535() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, TEST_FILE("qtbug_22535.qml")); + QDeclarativeContext context(engine.rootContext()); + + QObject *o = component.create(&context); + + // Don't crash! + delete o; +} + QTEST_MAIN(tst_qdeclarativecontext) #include "tst_qdeclarativecontext.moc"