QVarLengthArray: fix UBs in insert(it, n, v) ([basic.life], invariants)
In the same vein as e24df8bc726d12e80f3f1d14834f9305586fcc98 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");
|
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
|
||||||
|
|
||||||
qsizetype offset = qsizetype(before - cbegin());
|
const qsizetype offset = qsizetype(before - cbegin());
|
||||||
if (n != 0) {
|
resize_impl(prealloc, array, size() + n, t);
|
||||||
const T copy(t); // `t` could alias an element in [begin(), end()[
|
const auto b = begin() + offset;
|
||||||
resize_impl(prealloc, array, size() + n);
|
const auto e = end();
|
||||||
if constexpr (!QTypeInfo<T>::isRelocatable) {
|
QtPrivate::q_rotate(b, e - n, e);
|
||||||
T *b = begin() + offset;
|
return b;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user