diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 456be91d032..ceb4553b635 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -917,6 +917,8 @@ template Q_INLINE_TEMPLATE QSharedPointer qSharedPointerObjectCast(const QSharedPointer &src) { X *ptr = qobject_cast(src.data()); + if (!ptr) + return QSharedPointer(); return QtSharedPointer::copyAndSetPointer(ptr, src); } template @@ -959,7 +961,9 @@ template std::shared_ptr qobject_pointer_cast(const std::shared_ptr &src) { using element_type = typename std::shared_ptr::element_type; - return std::shared_ptr(src, qobject_cast(src.get())); + if (auto ptr = qobject_cast(src.get())) + return std::shared_ptr(src, ptr); + return std::shared_ptr(); } template diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 772b3f827fc..b875aeda27d 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -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::create(); + auto qptr = QPointer(ptr.data()); + auto ptr2 = ptr.objectCast(); + + QVERIFY(ptr); + QVERIFY(qptr); + QVERIFY(!ptr2); + + ptr.reset(); + QVERIFY(!ptr); + QVERIFY(!qptr); +} void tst_QSharedPointer::objectCastStdSharedPtr() {