Don't increase the refcount if qobject_cast failed

Follow the dynamicCast/dynamic_pointer_cast implementation for
objectCast/object_pointer_cast since a qobject_cast can fail
just like a dynamic dast.
Also see: https://eel.is/c++draft/util.smartptr.shared.cast#6.2

See commit this commit from 2013 for more historical context:
a094bf5a893c3cccffff10c1420bfbe3a3c02a7c

Pick-to: 6.7 6.5
Change-Id: I9a54af55a7a1cf106cace52e9cf3bc103ae0bd42
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 7a65abb50eb638de445e24c2746d7f90c1b89f06)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Milian Wolff 2024-08-08 11:40:03 +02:00 committed by Qt Cherry-pick Bot
parent 9da25cc13c
commit ba6ffd99e2
2 changed files with 21 additions and 1 deletions

View File

@ -917,6 +917,8 @@ template <class X, class T>
Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
{
X *ptr = qobject_cast<X *>(src.data());
if (!ptr)
return QSharedPointer<X>();
return QtSharedPointer::copyAndSetPointer(ptr, src);
}
template <class X, class T>
@ -959,7 +961,9 @@ template <typename X, class T>
std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
{
using element_type = typename std::shared_ptr<X>::element_type;
return std::shared_ptr<X>(src, qobject_cast<element_type *>(src.get()));
if (auto ptr = qobject_cast<element_type *>(src.get()))
return std::shared_ptr<X>(src, ptr);
return std::shared_ptr<X>();
}
template <typename X, class T>

View File

@ -57,6 +57,7 @@ private slots:
void weakQObjectFromSharedPointer();
void objectCast();
void objectCastStdSharedPtr();
void objectCastFailureNoLeak();
void differentPointers();
void virtualBaseDifferentPointers();
void virtualBaseWeakPointerConversions();
@ -1109,6 +1110,21 @@ void tst_QSharedPointer::objectCast()
safetyCheck();
}
void tst_QSharedPointer::objectCastFailureNoLeak()
{
// verify that a failing object cast doesn't keep the original object alive
auto ptr = QSharedPointer<QObject>::create();
auto qptr = QPointer(ptr.data());
auto ptr2 = ptr.objectCast<tst_QSharedPointer>();
QVERIFY(ptr);
QVERIFY(qptr);
QVERIFY(!ptr2);
ptr.reset();
QVERIFY(!ptr);
QVERIFY(!qptr);
}
void tst_QSharedPointer::objectCastStdSharedPtr()
{