diff options
-rw-r--r-- | src/corelib/tools/qmap.h | 18 | ||||
-rw-r--r-- | tests/manual/corelib/tools/qmap/main.cpp | 111 | ||||
-rw-r--r-- | tests/manual/corelib/tools/qmap/qmaptest.pro | 2 |
3 files changed, 131 insertions, 0 deletions
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 449fcbca0a..8c15afd9f8 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -557,6 +557,18 @@ public: private: void detach_helper(); + bool isValidIterator(const const_iterator &ci) const + { +#if defined(QT_DEBUG) && !defined(Q_MAP_NO_ITERATOR_DEBUG) + const QMapNodeBase *n = ci.i; + while (n->parent()) + n = n->parent(); + return n->left == d->root(); +#else + Q_UNUSED(ci); + return true; +#endif + } }; template <class Key, class T> @@ -670,6 +682,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K if (d->ref.isShared()) return this->insert(akey, avalue); + Q_ASSERT_X(isValidIterator(pos), "QMap::insert", "The specified const_iterator argument 'it' is invalid"); + if (pos == constEnd()) { // Hint is that the Node is larger than (or equal to) the largest value. Node *n = static_cast<Node *>(pos.i->left); @@ -753,6 +767,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co if (d->ref.isShared()) return this->insertMulti(akey, avalue); + Q_ASSERT_X(isValidIterator(pos), "QMap::insertMulti", "The specified const_iterator argument 'pos' is invalid"); + if (pos == constEnd()) { // Hint is that the Node is larger than (or equal to) the largest value. Node *n = static_cast<Node *>(pos.i->left); @@ -895,6 +911,8 @@ Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterato if (it == iterator(d->end())) return it; + Q_ASSERT_X(isValidIterator(const_iterator(it)), "QMap::erase", "The specified iterator argument 'it' is invalid"); + Node *n = it.i; ++it; d->deleteNode(n); diff --git a/tests/manual/corelib/tools/qmap/main.cpp b/tests/manual/corelib/tools/qmap/main.cpp new file mode 100644 index 0000000000..0d88e3f170 --- /dev/null +++ b/tests/manual/corelib/tools/qmap/main.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//#define Q_NO_DEBUGMAP_PARENT_TEST +// Comment in line above to skip the parent test. +#include <QtCore/QMap> +#include <QDebug> + +void noBugErase() +{ + QMap<int, int> a, b; + a[10] = 11; + a[11] = 12; + b = a; + b.erase(b.begin()); +} + +void noBugInsertWithHints() +{ + QMap<int, int> a; + QMap<int, int> b; + for (int u = 100; u < 10000; u += 20) + a.insert(u, u); + b = a; + QMap<int, int>::const_iterator b_ite(b.begin()); // b.begin() ensures correct detach() + ++b_ite; + b.insert(b_ite, 501, 501); + b.insert(b_ite, 115, 115); + QMap<int, int> c; + c = b; + c.setSharable(false); +} + +void testInsertWithHintCorruption() +{ + qDebug() << "Starting testInsertWithHintCorruption"; + + QMap<int, int> a; + QMap<int, int> b; + for (int u = 100; u < 10000; u += 20) + a.insert(u, u); + b = a; + QMap<int, int>::const_iterator b_ite = b.constBegin(); + ++b_ite; + b.insert(b_ite, 501, 501); + b.insert(b_ite, 115, 115); // insert with wrong hint. + QMap<int, int> c; + c = b; + c.setSharable(false); + qDebug() << "End of testInsertWithHintCorruption - failed silently"; +} + +void testEraseCorruption() +{ + qDebug() << "Starting testEraseCorruption"; + + QMap<int, int> a, b; + a[10] = 11; + a[11] = 12; + b = a; + b.erase(a.begin()); + qDebug() << "End of testEraseCorruption - failed silently"; +} + +int main() +{ + noBugErase(); + noBugInsertWithHints(); + + // testEraseCorruption(); + testInsertWithHintCorruption(); + return 0; +} diff --git a/tests/manual/corelib/tools/qmap/qmaptest.pro b/tests/manual/corelib/tools/qmap/qmaptest.pro new file mode 100644 index 0000000000..fbe7013144 --- /dev/null +++ b/tests/manual/corelib/tools/qmap/qmaptest.pro @@ -0,0 +1,2 @@ +TEMPLATE = app +SOURCES = main.cpp |