diff options
-rw-r--r-- | src/corelib/tools/qhash.h | 5 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qhash/tst_qhash.cpp | 19 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 121ffa9fde..392371ce5e 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -51,6 +51,8 @@ #include <initializer_list> #include <functional> // for std::hash +class tst_QHash; // for befriending + QT_BEGIN_NAMESPACE struct QHashDummyValue @@ -680,7 +682,7 @@ struct Data } // return correct position of the next element - if (!spans[span].hasNode(index)) + if (bucket == numBuckets - 1 || !spans[span].hasNode(index)) ++it; return it; } @@ -740,6 +742,7 @@ class QHash using Data = QHashPrivate::Data<Node>; friend class QSet<Key>; friend class QMultiHash<Key, T>; + friend tst_QHash; Data *d = nullptr; diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index d77160ba19..6ad7d15c77 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -42,6 +42,7 @@ class tst_QHash : public QObject private slots: void insert1(); void erase(); + void erase_edge_case(); void key(); void swap(); @@ -532,6 +533,24 @@ void tst_QHash::erase() QVERIFY(mit == h2.end()); } +/* + With a specific seed we could end up in a situation where, upon deleting the + last entry in a QHash, the returned iterator would not point to the end() + iterator. +*/ +void tst_QHash::erase_edge_case() +{ + QHash<int, int> h1; + h1.reserve(2); + h1.d->seed = 10230148258692185509ull; + h1.insert(3, 4); + h1.insert(5, 6); + QHash<int, int>::iterator it1 = h1.begin(); + ++it1; + it1 = h1.erase(it1); + QVERIFY(it1 == h1.end()); +} + void tst_QHash::key() { { |