diff options
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 2 | ||||
-rw-r--r-- | src/corelib/tools/qvarlengtharray.h | 19 | ||||
-rw-r--r-- | src/corelib/tools/qvector.h | 27 |
3 files changed, 30 insertions, 18 deletions
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 8abb57586b..618b31e391 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -881,7 +881,7 @@ Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2) template <class T> Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr, uint seed = 0) { - return QT_PREPEND_NAMESPACE(qHash)(ptr.data(), seed); + return qHash(ptr.data(), seed); } diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 0110956b77..d8c229dea8 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -152,19 +152,18 @@ public: if (s == a) { // i.e. s != 0 T copy(t); realloc(s, s<<1); - const int idx = s++; - new (ptr + idx) T(std::move(copy)); + new (end()) T(std::move(copy)); } else { - const int idx = s++; - new (ptr + idx) T(t); + new (end()) T(t); } + ++s; } void append(T &&t) { if (s == a) realloc(s, s << 1); - const int idx = s++; - new (ptr + idx) T(std::move(t)); + new (end()) T(std::move(t)); + ++s; } void append(const T *buf, int size); @@ -501,7 +500,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA } template <class T, int Prealloc> -Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t) +Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, int n, const T &t) { Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid"); @@ -538,6 +537,12 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA int f = int(abegin - ptr); int l = int(aend - ptr); int n = l - f; + + if (n == 0) // avoid UB in std::copy() below + return data() + f; + + Q_ASSERT(n > 0); // aend must be reachable from abegin + if (QTypeInfo<T>::isComplex) { std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f)); T *i = ptr + s; diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 6acbf3561e..85393a3598 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -835,18 +835,25 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c if (!isDetached() || d->size + n > int(d->alloc)) realloc(d->size + n, QArrayData::Grow); if (!QTypeInfoQuery<T>::isRelocatable) { - T *b = d->end(); - T *i = d->end() + n; - while (i != b) - new (--i) T; - i = d->end(); + T *const e = d->end(); + T *const b = d->begin() + offset; + + T *i = e; T *j = i + n; - b = d->begin() + offset; - while (i != b) - *--j = *--i; - i = b+n; + + // move old elements into the uninitialized space + while (i != b && j > e) + new (--j) T(std::move(*--i)); + // move the rest of old elements into the tail using assignment while (i != b) - *--i = copy; + *--j = std::move(*--i); + + // construct copies of t inside the uninitialized space + while (j != b && j > e) + new (--j) T(copy); + // use assignment to fill the recently-moved-from space + while (j != b) + *--j = copy; } else { T *b = d->begin() + offset; T *i = b + n; |