Fix hashing of QPersistentModelIndex

The hash and equality operators used need to be consistent with
each other. Unfortunately, QPMI::operator==() is not suitable to do
this. So specialize qHashEquals() for QPMI.

Fixes: QTBUG-88966
Change-Id: If5f19a722ae9fc4e78e93537e7ea15726f148768
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 83e95956ed58e88b11e2cc3cb61c5beacb7985db)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Lars Knoll 2020-12-03 09:04:07 +01:00 committed by Qt Cherry-pick Bot
parent 793dbd8ee6
commit 6012285e7d
2 changed files with 36 additions and 0 deletions

View File

@ -242,6 +242,8 @@ public:
private: private:
QPersistentModelIndexData *d; QPersistentModelIndexData *d;
friend size_t qHash(const QPersistentModelIndex &, size_t seed) noexcept; friend size_t qHash(const QPersistentModelIndex &, size_t seed) noexcept;
friend bool qHashEquals(const QPersistentModelIndex &a, const QPersistentModelIndex &b) noexcept
{ return a.d == b.d; }
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &); friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
#endif #endif

View File

@ -252,6 +252,7 @@ private slots:
void taskQTBUG_61476(); void taskQTBUG_61476();
void testInitialFocus(); void testInitialFocus();
void fetchUntilScreenFull(); void fetchUntilScreenFull();
void expandAfterTake();
}; };
class QtTestModel: public QAbstractItemModel class QtTestModel: public QAbstractItemModel
@ -5218,6 +5219,39 @@ void tst_QTreeView::fetchUntilScreenFull()
QVERIFY(expectedItemNumberFetched); QVERIFY(expectedItemNumberFetched);
} }
static void populateModel(QStandardItemModel *model)
{
const int depth = 10;
for (int i1 = 0; i1 < depth; ++i1) {
QStandardItem *s1 = new QStandardItem;
s1->setText(QString::number(i1));
model->appendRow(s1);
for (int i2 = 0; i2 < depth; ++i2) {
QStandardItem *s2 = new QStandardItem;
s2->setText(QStringLiteral("%1 - %2").arg(i1).arg(i2));
s1->appendRow(s2);
for (int i3 = 0; i3 < depth; ++i3) {
QStandardItem *s3 = new QStandardItem;
s3->setText(QStringLiteral("%1 - %2 - %3").arg(i1).arg(i2).arg(i3));
s2->appendRow(s3);
}
}
}
}
void tst_QTreeView::expandAfterTake()
{
QStandardItemModel model;
populateModel(&model);
QTreeView view;
view.setUniformRowHeights(true);
view.setModel(&model);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
view.expandAll();
model.takeItem(0);
populateModel(&model); // populate model again, having corrupted items inside QTreeViewPrivate::expandedIndexes
view.expandAll(); // adding new items to QTreeViewPrivate::expandedIndexes with corrupted persistent indices, causing crash sometimes
}
QTEST_MAIN(tst_QTreeView) QTEST_MAIN(tst_QTreeView)
#include "tst_qtreeview.moc" #include "tst_qtreeview.moc"