From 87679491cb21088223fcd656e0e49793874e4a9e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 15 Dec 2011 07:24:49 +0100 Subject: 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 Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qobject.cpp | 2 +- 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() -- cgit v1.2.3