QMultiHash: fix missing update to m_size
QMultiHash has access to two sizes: one of them is shared with QHash, stored in QHashPrivate::Data::size, which counts keys; the other, which is what our public size() function returns, is stored in QMultiHash::m_size and counts plain (key,value) entries. We forgot to update it in the non-const operator[] that created a node. I've reviewed the rest of the code and can't find any more places where the item count may be changed and m_size isn't updated. [ChangeLog][QtCore][QMultiHash] Fixed a bug that caused an element that was created by operator[] to not be counted, resulting in a hash map with an incorrect element count and which could cause an assertion failure depending on how the hash was later mutated. Fixes: QTBUG-112534 Pick-to: 6.2 6.4 6.5 Change-Id: Idd5e1bb52be047d7b4fffffd17527ec274e1d99e Reviewed-by: Lars Knoll <lars@knoll.priv.no>
This commit is contained in:
parent
59466abc08
commit
87103e04e9
@ -1632,8 +1632,10 @@ public:
|
||||
detach();
|
||||
auto result = d->findOrInsert(key);
|
||||
Q_ASSERT(!result.it.atEnd());
|
||||
if (!result.initialized)
|
||||
if (!result.initialized) {
|
||||
Node::createInPlace(result.it.node(), key, T());
|
||||
++m_size;
|
||||
}
|
||||
return result.it.node()->value->value;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ private slots:
|
||||
void qmultihash_qhash_rvalue_ref_ctor();
|
||||
void qmultihash_qhash_rvalue_ref_unite();
|
||||
void qmultihashUnite();
|
||||
void qmultihashSize();
|
||||
|
||||
void compare();
|
||||
void compare2();
|
||||
@ -2051,6 +2052,78 @@ void tst_QHash::qmultihashUnite()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QHash::qmultihashSize()
|
||||
{
|
||||
// QMultiHash has an extra m_size member that counts the number of values,
|
||||
// while d->size (shared with QHash) counts the number of distinct keys.
|
||||
{
|
||||
QMultiHash<int, int> hash;
|
||||
QCOMPARE(hash.size(), 0);
|
||||
QVERIFY(hash.isEmpty());
|
||||
|
||||
hash.insert(0, 42);
|
||||
QCOMPARE(hash.size(), 1);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
hash.insert(0, 42);
|
||||
QCOMPARE(hash.size(), 2);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
hash.emplace(0, 42);
|
||||
QCOMPARE(hash.size(), 3);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
QCOMPARE(hash.take(0), 42);
|
||||
QCOMPARE(hash.size(), 2);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
QCOMPARE(hash.remove(0), 2);
|
||||
QCOMPARE(hash.size(), 0);
|
||||
QVERIFY(hash.isEmpty());
|
||||
}
|
||||
|
||||
{
|
||||
QMultiHash<int, int> hash;
|
||||
hash.emplace(0, 0);
|
||||
hash.emplace(0, 0);
|
||||
QCOMPARE(hash.size(), 2);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
hash.emplace(0, 1);
|
||||
QCOMPARE(hash.size(), 3);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
QCOMPARE(hash.remove(0, 0), 2);
|
||||
QCOMPARE(hash.size(), 1);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
hash.remove(0);
|
||||
QCOMPARE(hash.size(), 0);
|
||||
QVERIFY(hash.isEmpty());
|
||||
}
|
||||
|
||||
{
|
||||
QMultiHash<int, int> hash;
|
||||
|
||||
hash[0] = 0;
|
||||
QCOMPARE(hash.size(), 1);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
hash.replace(0, 1);
|
||||
QCOMPARE(hash.size(), 1);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
hash.insert(0, 1);
|
||||
hash.erase(hash.cbegin());
|
||||
QCOMPARE(hash.size(), 1);
|
||||
QVERIFY(!hash.isEmpty());
|
||||
|
||||
hash.erase(hash.cbegin());
|
||||
QCOMPARE(hash.size(), 0);
|
||||
QVERIFY(hash.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QHash::keys_values_uniqueKeys()
|
||||
{
|
||||
QMultiHash<QString, int> hash;
|
||||
|
Loading…
Reference in New Issue
Block a user