QArrayDataPointer: remove Q_CHECK_PTR in assign(it, it) again

This commit reverts 2d77051f9d.

When requesting an allocation of size 0, we will actually get
a nullptr.

 qarraydata.cpp:
    ~~~
    if (capacity == 0) {
        *dptr = nullptr;
        return nullptr;
    }

This will let the Q_CHECK_PTR trigger falsely. Such an occurrence was
initially detected during the cmake_automoc_parser build-step.

Found-by: Marc Mutz <marc.mutz@qt.io>
Task-number: QTBUG-106196
Pick-to: 6.6
Change-Id: Icb68c5dd518c9623119a61d5c4fdcff43dc4ac5d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Dennis Oberst 2023-08-16 18:25:41 +02:00
parent 02e2a3f123
commit 3db9ef358d
2 changed files with 20 additions and 2 deletions

View File

@ -327,12 +327,10 @@ public:
const qsizetype n = std::distance(first, last); const qsizetype n = std::distance(first, last);
if (needsDetach() || n > constAllocatedCapacity()) { if (needsDetach() || n > constAllocatedCapacity()) {
QArrayDataPointer allocated(Data::allocate(detachCapacity(n))); QArrayDataPointer allocated(Data::allocate(detachCapacity(n)));
Q_CHECK_PTR(allocated.data());
swap(allocated); swap(allocated);
} }
} else if (needsDetach()) { } else if (needsDetach()) {
QArrayDataPointer allocated(Data::allocate(allocatedCapacity())); QArrayDataPointer allocated(Data::allocate(allocatedCapacity()));
Q_CHECK_PTR(allocated.data());
swap(allocated); swap(allocated);
// We don't want to copy data that we know we'll overwrite // We don't want to copy data that we know we'll overwrite
} }

View File

@ -231,6 +231,7 @@ private slots:
void appendCustom() const { append<Custom>(); } void appendCustom() const { append<Custom>(); }
void appendRvalue() const; void appendRvalue() const;
void appendList() const; void appendList() const;
void assignEmpty() const;
void assignInt() const { assign<int>(); } void assignInt() const { assign<int>(); }
void assignMovable() const { assign<Movable>(); } void assignMovable() const { assign<Movable>(); }
void assignCustom() const { assign<Custom>(); } void assignCustom() const { assign<Custom>(); }
@ -759,6 +760,25 @@ void tst_QList::append() const
} }
} }
void tst_QList::assignEmpty() const
{
// Test that the realloc branch in assign(it, it) doesn't crash.
using T = int;
QList<T> list;
QList<T> ref1 = list;
QVERIFY(list.d.needsDetach());
list.assign(list.begin(), list.begin());
#if !defined Q_OS_QNX // QNX has problems with the empty istream_iterator
auto empty = std::istream_iterator<T>{};
list.squeeze();
QCOMPARE_EQ(list.capacity(), 0);
ref1 = list;
QVERIFY(list.d.needsDetach());
list.assign(empty, empty);
#endif
}
template <typename T> template <typename T>
void tst_QList::assign() const void tst_QList::assign() const
{ {