diff options
author | Olivier Goffart <ogoffart@woboq.com> | 2011-12-15 07:24:49 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-19 14:06:12 +0100 |
commit | 87679491cb21088223fcd656e0e49793874e4a9e (patch) | |
tree | 5b3bdb6bc76ee39ab73f3114d6e870493d712ca6 | |
parent | bbc098ab9fde2caefa8e373a0fcdadfa95edddda (diff) |
Do not call QueuedConnection slot on partialy destroyed object
This is a regression introduced in Qt 4.8
When QApplication::processEvents is called from a destructor, it is
possible that pending events would still be called on the already
destroyed subclass.
Prevent that by using the same pattern as in QMetaObject::activate
Change-Id: Ida50db07ae089264402dafcde7a41a066479d08b
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 2 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 21 |
2 files changed, 18 insertions, 5 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 295322551f..febe90943b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -429,7 +429,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object) { if (slotObj_) { slotObj_->call(object, args_); - } else if (callFunction_) { + } else if (callFunction_ && method_offset_ <= object->metaObject()->methodOffset()) { callFunction_(object, QMetaObject::InvokeMetaMethod, method_relative_, args_); } else { QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method_offset_ + method_relative_, args_); diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 225e06a552..1e690386dc 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -4101,12 +4101,25 @@ public slots: } }; +static void processEvents() +{ + qApp->processEvents(); +} + void tst_QObject::baseDestroyed() { - BaseDestroyed d; - connect(&d, SIGNAL(destroyed()), &d, SLOT(slotUseList())); - //When d goes out of scope, slotUseList should not be called as the BaseDestroyed has - // already been destroyed while ~QObject emit destroyed + { + BaseDestroyed d; + connect(&d, SIGNAL(destroyed()), &d, SLOT(slotUseList())); + //When d goes out of scope, slotUseList should not be called as the BaseDestroyed has + // already been destroyed while ~QObject emit destroyed + } + { + BaseDestroyed d; + connect(&d, &QObject::destroyed, processEvents); + QMetaObject::invokeMethod(&d, "slotUseList", Qt::QueuedConnection); + //the destructor will call processEvents, that should not call the slotUseList + } } void tst_QObject::pointerConnect() |