From f9ea1604a570f88e9491a845ab2bcbb96fd6b6b7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 19 Jul 2023 21:24:14 +0200 Subject: [PATCH] Port QObjectPrivate::connectImpl() to SlotObjUniquePtr internally ... removing the custom scope-guard which was .dismiss()ed too early (the allocation of 'c' could theoretically fail, and the old code would leak the slot object in that case; nothing we're generally guarding against in Qt, but it's a nice drive-by gain, probably shuts up static checkers, and makes readers wonder less about the lifetime of the slot object). As mentioned in the patch porting QObject::connectImpl(), leave the unique_ptr out of the function's signature, see there for rationale (key-word: tail-callability). Change-Id: Ib90371b9768a72fd62d080b71eef2c82f851db81 Reviewed-by: Thiago Macieira (cherry picked from commit 18857db2dd0ededda0c9a6ba1731327f4121042a) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qobject.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1b257853526..079f3eb867b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -5073,14 +5073,10 @@ static void connectWarning(const QObject *sender, */ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int signal_index, const QObject *receiver, void **slot, - QtPrivate::QSlotObjectBase *slotObj, int type, + QtPrivate::QSlotObjectBase *slotObjRaw, int type, const int *types, const QMetaObject *senderMetaObject) { - auto connectFailureGuard = qScopeGuard([&]() - { - if (slotObj) - slotObj->destroyIfLastRef(); - }); + QtPrivate::SlotObjUniquePtr slotObj(slotObjRaw); if (!sender || !receiver || !slotObj || !senderMetaObject) { connectWarning(sender, senderMetaObject, receiver, "invalid nullptr parameter"); @@ -5092,8 +5088,6 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s return QMetaObject::Connection(); } - connectFailureGuard.dismiss(); - QObject *s = const_cast(sender); QObject *r = const_cast(receiver); @@ -5106,10 +5100,8 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s const QObjectPrivate::Connection *c2 = connections->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed(); while (c2) { - if (c2->receiver.loadRelaxed() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) { - slotObj->destroyIfLastRef(); + if (c2->receiver.loadRelaxed() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) return QMetaObject::Connection(); - } c2 = c2->nextConnectionList.loadRelaxed(); } } @@ -5129,9 +5121,9 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s td->ref(); c->receiverThreadData.storeRelaxed(td); c->receiver.storeRelaxed(r); - c->slotObj = slotObj; c->connectionType = type; c->isSlotObject = true; + c->slotObj = slotObj.release(); if (types) { c->argumentTypes.storeRelaxed(types); c->ownArgumentTypes = false;