summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2021-12-06 19:21:54 +0100
committerMårten Nordheim <marten.nordheim@qt.io>2021-12-07 03:07:49 +0100
commit78df625510b73d7b7709be16f9a168ba8c3f4d19 (patch)
tree27402fb8c763d625b0b699406a9363a83416e691
parentb781915c393e0abc456eedf90adf5b630693eab6 (diff)
QMultiHash: fix erase returning the wrong iterator
When deleting the last item in a chain, without it being the last item in the chain, then we re-use the iterator which was passed in as an argument. This is wrong if we detached earlier in the function, and means we return an iterator to the previously shared data. Pick-to: 6.2 Change-Id: I7da6309e23a32073da59e7da0cbfd1d16734f1ca Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
-rw-r--r--src/corelib/tools/qhash.h5
-rw-r--r--tests/auto/corelib/tools/qhash/tst_qhash.cpp16
2 files changed, 19 insertions, 2 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 24fd24e603..d9dfda71c1 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -1778,7 +1778,8 @@ public:
iterator erase(const_iterator it)
{
Q_ASSERT(d);
- iterator i = detach(it);
+ iterator iter = detach(it);
+ iterator i = iter;
Chain *e = *i.e;
Chain *next = e->next;
*i.e = next;
@@ -1788,7 +1789,7 @@ public:
// last remaining entry, erase
i = iterator(d->erase(i.i));
} else {
- i = iterator(++it.i);
+ i = iterator(++iter.i);
}
}
--m_size;
diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
index 7cc4d3d0f0..11e7237ba4 100644
--- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp
+++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
@@ -550,6 +550,22 @@ void tst_QHash::erase()
auto mit = h2.erase(bit);
mit = h2.erase(h2.begin());
QVERIFY(mit == h2.end());
+
+ h2 = QMultiHash<int, int>();
+ h2.emplace(1, 1);
+ h2.emplace(1, 2);
+ h2.emplace(3, 1);
+ h2.emplace(3, 4);
+ QMultiHash<int, int> h3 = h2;
+ auto it = h3.constFind(3);
+ ++it;
+ QVERIFY(h3.isSharedWith(h2));
+ it = h3.erase(it);
+ QVERIFY(!h3.isSharedWith(h2));
+ if (it != h3.cend()) {
+ auto it2 = h3.constFind(it.key());
+ QCOMPARE(it, it2);
+ }
}
/*