From 448674a68da65b038211e3d87c9ff87e557f7ce2 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Fri, 23 Jul 2021 14:08:33 +0200 Subject: QHash/QSet: fix squeeze() for default-constructed container QHash::squeeze() was unconditionally calling reserve(0), which is always allocating memory (even for 0 size). This was leading to a confusing situation when calling squeeze() on a default-constructed container with 0 capacity() actually allocated memory. This is very misleading, as squeeze() is supposed to free unneeded memory, not to allocate more. This patch adds a check for non-zero capacity. As a result, nothing is done for default-constructed container. Note that this patch also affects the QSet::squeeze() behavior, because QSet uses QHash as its underlying data type. Task-number: QTBUG-91736 Change-Id: Ib1c3c8b7b3de6ddeefea0e70b1ec71803e8fd3b3 Reviewed-by: Edward Welbourne Reviewed-by: Andreas Buhr (cherry picked from commit b095d268788343b67a3995db7148dcc3af9bde1a) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/tools/qhash.h | 6 +++++- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 2 ++ tests/auto/corelib/tools/qset/tst_qset.cpp | 8 ++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 624d647c72..25c00ce26f 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -850,7 +850,11 @@ public: else d = Data::detached(d, size_t(size)); } - inline void squeeze() { reserve(0); } + inline void squeeze() + { + if (capacity()) + reserve(0); + } inline void detach() { if (!d || d->ref.isShared()) d = Data::detached(d); } inline bool isDetached() const noexcept { return d && !d->ref.isShared(); } diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 0ca37b5f7a..3c873d093e 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -2587,6 +2587,8 @@ void tst_QHash::fineTuningInEmptyHash() { QHash hash; QCOMPARE(hash.capacity(), 0); + hash.squeeze(); + QCOMPARE(hash.capacity(), 0); QVERIFY(qFuzzyIsNull(hash.load_factor())); QVERIFY(!hash.isDetached()); diff --git a/tests/auto/corelib/tools/qset/tst_qset.cpp b/tests/auto/corelib/tools/qset/tst_qset.cpp index 2911f822e0..490e8e97fd 100644 --- a/tests/auto/corelib/tools/qset/tst_qset.cpp +++ b/tests/auto/corelib/tools/qset/tst_qset.cpp @@ -244,12 +244,12 @@ void tst_QSet::reserve() void tst_QSet::squeeze() { QSet set; - int n = set.capacity(); - QVERIFY(n == 0); + QCOMPARE(set.capacity(), 0); set.squeeze(); - n = set.capacity(); - QVERIFY(n > 0 && n < 100); + QCOMPARE(set.capacity(), 0); + + QVERIFY(!set.isDetached()); set.reserve(1000); QVERIFY(set.capacity() >= 1000); -- cgit v1.2.3