summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2013-05-07 18:56:50 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-09 08:23:48 +0200
commit9cc106d9d7d951fcf30f4b0f8606afa6b50892ec (patch)
tree355982010d6eacc5352db0b10be1c6b180c6266c
parentbaa28220777774c619f132977f5d0f7cd0775226 (diff)
Fix a case of connect()ing to signals declared in a base class
Fix connection to pointer to member signal that belongs to the base class, but whose type is a pointer to a member of the derived class. The current code only use the QMetaObject of the type coming from the function type to look up the signal id. But if the signal was casted to a pointer to member function of a derived type, then we also need to look in the base classes Change-Id: Ib98fc38f63942946acb34d9f83c100991d58e4e5 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/kernel/qobject.cpp10
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp25
2 files changed, 32 insertions, 3 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 527a842d17..d4d2d527d4 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4288,9 +4288,13 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
}
int signal_index = -1;
void *args[] = { &signal_index, signal };
- senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
- if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
- qWarning("QObject::connect: signal not found in %s", senderMetaObject->className());
+ for (; senderMetaObject && signal_index < 0; senderMetaObject = senderMetaObject->superClass()) {
+ senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
+ if (signal_index >= 0 && signal_index < QMetaObjectPrivate::get(senderMetaObject)->signalCount)
+ break;
+ }
+ if (!senderMetaObject) {
+ qWarning("QObject::connect: signal not found in %s", sender->metaObject()->className());
slotObj->destroyIfLastRef();
return QMetaObject::Connection(0);
}
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 06fc89f657..d16369de02 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -145,6 +145,7 @@ private slots:
void connectFunctorArgDifference();
void connectFunctorOverloads();
void disconnectDoesNotLeakFunctor();
+ void connectBase();
};
struct QObjectCreatedOnShutdown
@@ -5811,5 +5812,29 @@ void tst_QObject::disconnectDoesNotLeakFunctor()
QCOMPARE(countedStructObjectsCount, 0);
}
+class SubSender : public SenderObject {
+ Q_OBJECT
+};
+
+void tst_QObject::connectBase()
+{
+ SubSender sub;
+ ReceiverObject r1;
+ r1.reset();
+
+ QVERIFY( connect( &sub, &SubSender::signal1 , &r1, &ReceiverObject::slot1 ) );
+ QVERIFY( connect( &sub, static_cast<void (SenderObject::*)()>(&SubSender::signal2) , &r1, &ReceiverObject::slot2 ) );
+ QVERIFY( connect( &sub, static_cast<void (SubSender::*)()>(&SubSender::signal3) , &r1, &ReceiverObject::slot3 ) );
+
+ sub.emitSignal1();
+ sub.emitSignal2();
+ sub.emitSignal3();
+
+ QCOMPARE( r1.count_slot1, 1 );
+ QCOMPARE( r1.count_slot2, 1 );
+ QCOMPARE( r1.count_slot3, 1 );
+}
+
+
QTEST_MAIN(tst_QObject)
#include "tst_qobject.moc"