From 8387d87bdcf7dfb359515f44b17f523791bc8edb Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 2 Mar 2017 08:55:35 +0100 Subject: QDialogButtonGroup: Fix removal of deleted buttons As the destroyed() signal is emitted from ~QObject, it is not allowed to use static_cast to a QAbstractButton on that pointer anymore. And the qobject_cast will also fail which will keep a dangling pointer in the hash. Change-Id: If0d22fcc30cde87e771e70914c3afb04ea207289 Reviewed-by: Marc Mutz --- src/widgets/widgets/qdialogbuttonbox.cpp | 5 ++--- .../widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 23158cf82f..984669f29a 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -716,8 +716,7 @@ void QDialogButtonBox::removeButton(QAbstractButton *button) return; // Remove it from the standard button hash first and then from the roles - if (QPushButton *pushButton = qobject_cast(button)) - d->standardButtonHash.remove(pushButton); + d->standardButtonHash.remove(reinterpret_cast(button)); for (int i = 0; i < NRoles; ++i) { QList &list = d->buttonLists[i]; for (int j = 0; j < list.count(); ++j) { @@ -883,7 +882,7 @@ void QDialogButtonBoxPrivate::_q_handleButtonDestroyed() Q_Q(QDialogButtonBox); if (QObject *object = q->sender()) { QBoolBlocker skippy(internalRemove); - q->removeButton(static_cast(object)); + q->removeButton(reinterpret_cast(object)); } } diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index a35ea8eb6e..f127fd98f7 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -97,6 +97,8 @@ private slots: void testDefaultButton(); void task191642_default(); + void testDeletedStandardButton(); + private: qint64 timeStamp; qint64 buttonClicked1TimeStamp; @@ -843,5 +845,22 @@ void tst_QDialogButtonBox::task191642_default() QCOMPARE(clicked.count(), 1); } +void tst_QDialogButtonBox::testDeletedStandardButton() +{ + QDialogButtonBox buttonBox; + delete buttonBox.addButton(QDialogButtonBox::Ok); + QPointer buttonC = buttonBox.addButton(QDialogButtonBox::Cancel); + delete buttonBox.addButton(QDialogButtonBox::Cancel); + QPointer buttonA = buttonBox.addButton(QDialogButtonBox::Apply); + delete buttonBox.addButton(QDialogButtonBox::Help); + // A few button have been deleted, they should automatically be removed + QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Apply | QDialogButtonBox::Cancel); + + buttonBox.setStandardButtons(QDialogButtonBox::Reset | QDialogButtonBox::Cancel); + // setStanderdButton should delete previous buttons + QVERIFY(!buttonA); + QVERIFY(!buttonC); +} + QTEST_MAIN(tst_QDialogButtonBox) #include "tst_qdialogbuttonbox.moc" -- cgit v1.2.3