From bdc115d9698d4f3cf5ce089dbddca75e425d3eeb Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz Date: Sun, 14 Oct 2012 04:28:51 +0200 Subject: detach() safely in QVector::erase(), and update callers to not detach. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Olivier Goffart Reviewed-by: Konstantin Ritt --- src/corelib/tools/qvector.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') 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::insert(int i, int n, const T &t) template inline void QVector::remove(int i, int n) { Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= d->size, "QVector::remove", "index out of range"); - erase(begin() + i, begin() + i + n); } + erase(d->begin() + i, d->begin() + i + n); } template inline void QVector::remove(int i) { Q_ASSERT_X(i >= 0 && i < d->size, "QVector::remove", "index out of range"); - erase(begin() + i, begin() + i + 1); } + erase(d->begin() + i, d->begin() + i + 1); } template inline void QVector::prepend(const T &t) { insert(begin(), 1, t); } @@ -607,6 +607,8 @@ typename QVector::iterator QVector::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::isStatic) { iterator moveBegin = abegin + itemsToErase; iterator moveEnd = d->end(); -- cgit v1.2.3