QVarLengthArray: fix UBs in insert(it, n, v) ([basic.life], invariants)
In the same vein as e24df8bc72
for
emplace(it, v) and insert(it, rv), this patch addresses the identical
issues in insert(it, n, v). The solution is unsurprisingly the same:
q_rotate() after a resize(size() + n, v).
The 6.2- code will need to look different, because resize(n, v) didn't
exist there.
Pick-to: 6.5 6.4 6.2 5.15
Change-Id: I1ce91969abc20f2a1e5d05a8545b009a2e0994f6
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
147dd6e82f
commit
fed5f24454
@ -925,28 +925,12 @@ Q_OUTOFLINE_TEMPLATE auto QVLABase<T>::insert_impl(qsizetype prealloc, void *arr
|
||||
{
|
||||
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
|
||||
|
||||
qsizetype offset = qsizetype(before - cbegin());
|
||||
if (n != 0) {
|
||||
const T copy(t); // `t` could alias an element in [begin(), end()[
|
||||
resize_impl(prealloc, array, size() + n);
|
||||
if constexpr (!QTypeInfo<T>::isRelocatable) {
|
||||
T *b = begin() + offset;
|
||||
T *j = end();
|
||||
T *i = j - n;
|
||||
while (i != b)
|
||||
*--j = *--i;
|
||||
i = b + n;
|
||||
while (i != b)
|
||||
*--i = copy;
|
||||
} else {
|
||||
T *b = begin() + offset;
|
||||
T *i = b + n;
|
||||
memmove(static_cast<void *>(i), static_cast<const void *>(b), (size() - offset - n) * sizeof(T));
|
||||
while (i != b)
|
||||
q20::construct_at(--i, copy);
|
||||
}
|
||||
}
|
||||
return data() + offset;
|
||||
const qsizetype offset = qsizetype(before - cbegin());
|
||||
resize_impl(prealloc, array, size() + n, t);
|
||||
const auto b = begin() + offset;
|
||||
const auto e = end();
|
||||
QtPrivate::q_rotate(b, e - n, e);
|
||||
return b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
Loading…
Reference in New Issue
Block a user