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>
This commit is contained in:
Mårten Nordheim 2021-12-06 19:21:54 +01:00
parent b781915c39
commit 78df625510
2 changed files with 19 additions and 2 deletions

View File

@ -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;

View File

@ -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);
}
}
/*