summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Hartmetz <andreas.hartmetz@kdab.com>2012-10-14 04:28:51 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-19 18:04:11 +0200
commitbdc115d9698d4f3cf5ce089dbddca75e425d3eeb (patch)
tree07951c7374ebf7f7c82959872be0d00103e353a0 /src
parentc4ff5c53efc213d9ce4fe0cfe9ab3d6c13cd8716 (diff)
detach() safely in QVector::erase(), and update callers to not detach.
remove() can use non-detaching iterators internally before calling erase(), which hasn't been exploited so far, so that the detach() in erase() never actually detached. When using erase() from outside, you can't do it legally without calling begin() or end() that detach() before erase() is called. Now remove() doesn't detach anymore, and detaching in erase() works. With new tests that fail after changing only the erase() callers and pass again after fixing erase(). Change-Id: I47c0a9e362dce8628ec566f5437d951755de96c8 Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qvector.h10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 925ad17110..94733f77da 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -200,8 +200,8 @@ public:
typedef int size_type;
inline void push_back(const T &t) { append(t); }
inline void push_front(const T &t) { prepend(t); }
- void pop_back() { Q_ASSERT(!isEmpty()); erase(end()-1); }
- void pop_front() { Q_ASSERT(!isEmpty()); erase(begin()); }
+ void pop_back() { Q_ASSERT(!isEmpty()); erase(d->end() - 1); }
+ void pop_front() { Q_ASSERT(!isEmpty()); erase(d->begin()); }
inline bool empty() const
{ return d->size == 0; }
inline T& front() { return first(); }
@@ -366,11 +366,11 @@ inline void QVector<T>::insert(int i, int n, const T &t)
template <typename T>
inline void QVector<T>::remove(int i, int n)
{ Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= d->size, "QVector<T>::remove", "index out of range");
- erase(begin() + i, begin() + i + n); }
+ erase(d->begin() + i, d->begin() + i + n); }
template <typename T>
inline void QVector<T>::remove(int i)
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::remove", "index out of range");
- erase(begin() + i, begin() + i + 1); }
+ erase(d->begin() + i, d->begin() + i + 1); }
template <typename T>
inline void QVector<T>::prepend(const T &t)
{ insert(begin(), 1, t); }
@@ -607,6 +607,8 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
// FIXME we ara about to delete data maybe it is good time to shrink?
if (d->alloc) {
detach();
+ abegin = d->begin() + itemsUntouched;
+ aend = abegin + itemsToErase;
if (QTypeInfo<T>::isStatic) {
iterator moveBegin = abegin + itemsToErase;
iterator moveEnd = d->end();