From 4c4940a744558fc8faa713439d7e27e26b52774d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 1 Oct 2014 12:03:59 +0200 Subject: tst_QList: test all memory layouts The Movable type, surprisingly, was as large as sizeof(void*), so on 32-bit platforms, we were not testing the QList memory layout where items are placed directly into the void*-slots, but are too small, leaving gaps. Fixed by making sure that Movable is smaller than void* and adding a variant of Movable, Optimal, that is guaranteed to be the same size as void*, and replacing the int tests with tests of Optimal. Had to demote the State variable to uchar, since MSVC will apparently not make a collection of bit-fields smaller than the largest type used in any of the consituent bitfields, so State s : 8 wouldn't work. Change-Id: I4f0e24bd6928f076b4ce60e8d977d5d98a724161 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qlist/tst_qlist.cpp | 319 +++++++++++++++++++-------- 1 file changed, 226 insertions(+), 93 deletions(-) (limited to 'tests/auto') diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index 1e7b3ee2d6..95744051e4 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -79,14 +79,16 @@ private: static int liveCount; enum State { Constructed = 106, Destructed = 110 }; - State state; + uchar state; - static void check(const State state1, const State state2) + static void check(const uchar state1, const uchar state2) { QCOMPARE(state1, state2); } }; +Q_STATIC_ASSERT(sizeof(Movable) < sizeof(void*)); + int Movable::liveCount = 0; QT_BEGIN_NAMESPACE @@ -100,6 +102,75 @@ int qHash(const Movable& movable) return qHash(movable.i); } +struct Optimal +{ + Optimal(char input = 'j') + : i(input), + state(Constructed) + { + ++liveCount; + } + Optimal(const Optimal &other) + : i(other.i), + state(Constructed) + { + check(other.state, Constructed); + ++liveCount; + } + + ~Optimal() + { + check(state, Constructed); + i = 0; + --liveCount; + state = Destructed; + } + + bool operator ==(const Optimal &other) const + { + check(state, Constructed); + check(other.state, Constructed); + return i == other.i; + } + + Optimal &operator=(const Optimal &other) + { + check(state, Constructed); + check(other.state, Constructed); + i = other.i; + return *this; + } + char i; + + static int getLiveCount() { return liveCount; } +private: + static int liveCount; + + enum State { Constructed = 106, Destructed = 110 }; + uchar state; + char padding[sizeof(void*) - 2]; + + static void check(const uchar state1, const uchar state2) + { + QCOMPARE(state1, state2); + } +}; + +Q_STATIC_ASSERT(sizeof(Optimal) == sizeof(void*)); + +int Optimal::liveCount = 0; + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Optimal, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(Optimal); + +int qHash(const Optimal& key) +{ + return qHash(key.i); +} + struct Complex { Complex(int val = 0) @@ -160,6 +231,8 @@ Q_STATIC_ASSERT(!QTypeInfo::isStatic); Q_STATIC_ASSERT(!QTypeInfo::isComplex); Q_STATIC_ASSERT(!QTypeInfo::isStatic); Q_STATIC_ASSERT(QTypeInfo::isComplex); +Q_STATIC_ASSERT(!QTypeInfo::isStatic); +Q_STATIC_ASSERT(QTypeInfo::isComplex); Q_STATIC_ASSERT(QTypeInfo::isStatic); Q_STATIC_ASSERT(QTypeInfo::isComplex); @@ -168,100 +241,100 @@ class tst_QList : public QObject Q_OBJECT private slots: - void lengthInt() const; + void lengthOptimal() const; void lengthMovable() const; void lengthComplex() const; void lengthSignature() const; - void appendInt() const; + void appendOptimal() const; void appendMovable() const; void appendComplex() const; void prepend() const; - void midInt() const; + void midOptimal() const; void midMovable() const; void midComplex() const; - void atInt() const; + void atOptimal() const; void atMovable() const; void atComplex() const; - void firstInt() const; + void firstOptimal() const; void firstMovable() const; void firstComplex() const; - void lastInt() const; + void lastOptimal() const; void lastMovable() const; void lastComplex() const; - void beginInt() const; + void beginOptimal() const; void beginMovable() const; void beginComplex() const; - void endInt() const; + void endOptimal() const; void endMovable() const; void endComplex() const; - void containsInt() const; + void containsOptimal() const; void containsMovable() const; void containsComplex() const; - void countInt() const; + void countOptimal() const; void countMovable() const; void countComplex() const; - void emptyInt() const; + void emptyOptimal() const; void emptyMovable() const; void emptyComplex() const; - void endsWithInt() const; + void endsWithOptimal() const; void endsWithMovable() const; void endsWithComplex() const; - void lastIndexOfInt() const; + void lastIndexOfOptimal() const; void lastIndexOfMovable() const; void lastIndexOfComplex() const; - void moveInt() const; + void moveOptimal() const; void moveMovable() const; void moveComplex() const; - void removeAllInt() const; + void removeAllOptimal() const; void removeAllMovable() const; void removeAllComplex() const; - void removeAtInt() const; + void removeAtOptimal() const; void removeAtMovable() const; void removeAtComplex() const; - void removeOneInt() const; + void removeOneOptimal() const; void removeOneMovable() const; void removeOneComplex() const; - void replaceInt() const; + void replaceOptimal() const; void replaceMovable() const; void replaceComplex() const; - void startsWithInt() const; + void startsWithOptimal() const; void startsWithMovable() const; void startsWithComplex() const; - void swapInt() const; + void swapOptimal() const; void swapMovable() const; void swapComplex() const; - void takeAtInt() const; + void takeAtOptimal() const; void takeAtMovable() const; void takeAtComplex() const; - void takeFirstInt() const; + void takeFirstOptimal() const; void takeFirstMovable() const; void takeFirstComplex() const; - void takeLastInt() const; + void takeLastOptimal() const; void takeLastMovable() const; void takeLastComplex() const; - void toSetInt() const; + void toSetOptimal() const; void toSetMovable() const; void toSetComplex() const; - void toStdListInt() const; + void toStdListOptimal() const; void toStdListMovable() const; void toStdListComplex() const; - void toVectorInt() const; + void toVectorOptimal() const; void toVectorMovable() const; void toVectorComplex() const; - void valueInt() const; + void valueOptimal() const; void valueMovable() const; void valueComplex() const; - void testOperatorsInt() const; + void testOperatorsOptimal() const; void testOperatorsMovable() const; void testOperatorsComplex() const; - void testSTLIteratorsInt() const; + void testSTLIteratorsOptimal() const; void testSTLIteratorsMovable() const; void testSTLIteratorsComplex() const; void initializeList() const; - void constSharedNullInt() const; + void constSharedNullOptimal() const; void constSharedNullMovable() const; void constSharedNullComplex() const; void setSharableInt_data() const; @@ -320,7 +393,7 @@ template struct SimpleValue }; template<> -const int SimpleValue::values[] = { 10, 20, 30, 40, 100, 101, 102 }; +const Optimal SimpleValue::values[] = { 10, 20, 30, 40, 100, 101, 102 }; template<> const Movable SimpleValue::values[] = { 10, 20, 30, 40, 100, 101, 102 }; template<> @@ -369,9 +442,11 @@ void tst_QList::length() const } } -void tst_QList::lengthInt() const +void tst_QList::lengthOptimal() const { - length(); + const int liveCount = Optimal::getLiveCount(); + length(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::lengthMovable() const @@ -421,9 +496,11 @@ void tst_QList::append() const QCOMPARE(list1, listTotal); } -void tst_QList::appendInt() const +void tst_QList::appendOptimal() const { - append(); + const int liveCount = Optimal::getLiveCount(); + append(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::appendMovable() const @@ -486,9 +563,11 @@ void tst_QList::mid() const QCOMPARE(list1.mid(1, 1).length(), 0); } -void tst_QList::midInt() const +void tst_QList::midOptimal() const { - mid(); + const int liveCount = Optimal::getLiveCount(); + mid(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::midMovable() const @@ -534,9 +613,11 @@ void tst_QList::at() const QCOMPARE(list.at(2), T_CAT); } -void tst_QList::atInt() const +void tst_QList::atOptimal() const { - at(); + const int liveCount = Optimal::getLiveCount(); + at(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::atMovable() const @@ -567,9 +648,11 @@ void tst_QList::first() const QCOMPARE(list.first(), T_BAR); } -void tst_QList::firstInt() const +void tst_QList::firstOptimal() const { - first(); + const int liveCount = Optimal::getLiveCount(); + first(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::firstMovable() const @@ -600,9 +683,11 @@ void tst_QList::last() const QCOMPARE(list.last(), T_FOO); } -void tst_QList::lastInt() const +void tst_QList::lastOptimal() const { - last(); + const int liveCount = Optimal::getLiveCount(); + last(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::lastMovable() const @@ -633,9 +718,11 @@ void tst_QList::begin() const QCOMPARE(*list.begin(), T_BAR); } -void tst_QList::beginInt() const +void tst_QList::beginOptimal() const { - begin(); + const int liveCount = Optimal::getLiveCount(); + begin(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::beginMovable() const @@ -666,9 +753,11 @@ void tst_QList::end() const QCOMPARE(*--list.end(), T_FOO); } -void tst_QList::endInt() const +void tst_QList::endOptimal() const { - end(); + const int liveCount = Optimal::getLiveCount(); + end(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::endMovable() const @@ -699,9 +788,11 @@ void tst_QList::contains() const QVERIFY(list.contains(T_BLAH) == true); } -void tst_QList::containsInt() const +void tst_QList::containsOptimal() const { - contains(); + const int liveCount = Optimal::getLiveCount(); + contains(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::containsMovable() const @@ -743,9 +834,11 @@ void tst_QList::count() const QVERIFY(list.count() == 0); } -void tst_QList::countInt() const +void tst_QList::countOptimal() const { - count(); + const int liveCount = Optimal::getLiveCount(); + count(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::countMovable() const @@ -779,9 +872,11 @@ void tst_QList::empty() const QVERIFY(list.empty()); } -void tst_QList::emptyInt() const +void tst_QList::emptyOptimal() const { - empty(); + const int liveCount = Optimal::getLiveCount(); + empty(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::emptyMovable() const @@ -813,9 +908,11 @@ void tst_QList::endsWith() const QVERIFY(list.endsWith(T_BAR)); } -void tst_QList::endsWithInt() const +void tst_QList::endsWithOptimal() const { - endsWith(); + const int liveCount = Optimal::getLiveCount(); + endsWith(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::endsWithMovable() const @@ -856,9 +953,11 @@ void tst_QList::lastIndexOf() const QVERIFY(list.lastIndexOf(T_BAZ, 1) == -1); } -void tst_QList::lastIndexOfInt() const +void tst_QList::lastIndexOfOptimal() const { - lastIndexOf(); + const int liveCount = Optimal::getLiveCount(); + lastIndexOf(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::lastIndexOfMovable() const @@ -894,9 +993,11 @@ void tst_QList::move() const QCOMPARE(list, QList() << T_BAR << T_FOO << T_BAZ); } -void tst_QList::moveInt() const +void tst_QList::moveOptimal() const { - move(); + const int liveCount = Optimal::getLiveCount(); + move(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::moveMovable() const @@ -933,9 +1034,11 @@ void tst_QList::removeAll() const QCOMPARE(list, QList() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); } -void tst_QList::removeAllInt() const +void tst_QList::removeAllOptimal() const { - removeAll(); + const int liveCount = Optimal::getLiveCount(); + removeAll(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::removeAllMovable() const @@ -971,9 +1074,11 @@ void tst_QList::removeAt() const QCOMPARE(list, QList()); } -void tst_QList::removeAtInt() const +void tst_QList::removeAtOptimal() const { - removeAt(); + const int liveCount = Optimal::getLiveCount(); + removeAt(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::removeAtMovable() const @@ -1018,9 +1123,11 @@ void tst_QList::removeOne() const QCOMPARE(list, QList() << T_FOO); } -void tst_QList::removeOneInt() const +void tst_QList::removeOneOptimal() const { - removeOne(); + const int liveCount = Optimal::getLiveCount(); + removeOne(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::removeOneMovable() const @@ -1059,9 +1166,11 @@ void tst_QList::replace() const << T_DOG << T_BLAH); } -void tst_QList::replaceInt() const +void tst_QList::replaceOptimal() const { - replace(); + const int liveCount = Optimal::getLiveCount(); + replace(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::replaceMovable() const @@ -1092,9 +1201,11 @@ void tst_QList::startsWith() const QVERIFY(list.startsWith(T_BAR)); } -void tst_QList::startsWithInt() const +void tst_QList::startsWithOptimal() const { - startsWith(); + const int liveCount = Optimal::getLiveCount(); + startsWith(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::startsWithMovable() const @@ -1133,9 +1244,11 @@ void tst_QList::swap() const QCOMPARE(list2, QList() << T_BAZ << T_FOO << T_BAR); } -void tst_QList::swapInt() const +void tst_QList::swapOptimal() const { - swap(); + const int liveCount = Optimal::getLiveCount(); + swap(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::swapMovable() const @@ -1166,9 +1279,11 @@ void tst_QList::takeAt() const QVERIFY(list.size() == 0); } -void tst_QList::takeAtInt() const +void tst_QList::takeAtOptimal() const { - takeAt(); + const int liveCount = Optimal::getLiveCount(); + takeAt(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::takeAtMovable() const @@ -1199,9 +1314,11 @@ void tst_QList::takeFirst() const QVERIFY(list.size() == 0); } -void tst_QList::takeFirstInt() const +void tst_QList::takeFirstOptimal() const { - takeFirst(); + const int liveCount = Optimal::getLiveCount(); + takeFirst(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::takeFirstMovable() const @@ -1229,9 +1346,11 @@ void tst_QList::takeLast() const QCOMPARE(list.takeLast(), T_FOO); } -void tst_QList::takeLastInt() const +void tst_QList::takeLastOptimal() const { - takeLast(); + const int liveCount = Optimal::getLiveCount(); + takeLast(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::takeLastMovable() const @@ -1265,9 +1384,11 @@ void tst_QList::toSet() const << T_FOO << T_BAR << T_BAZ); } -void tst_QList::toSetInt() const +void tst_QList::toSetOptimal() const { - toSet(); + const int liveCount = Optimal::getLiveCount(); + toSet(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::toSetMovable() const @@ -1300,9 +1421,11 @@ void tst_QList::toStdList() const QCOMPARE(list, QList() << T_FOO << T_BAR << T_BAZ); } -void tst_QList::toStdListInt() const +void tst_QList::toStdListOptimal() const { - toStdList(); + const int liveCount = Optimal::getLiveCount(); + toStdList(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::toStdListMovable() const @@ -1328,9 +1451,11 @@ void tst_QList::toVector() const QCOMPARE(list.toVector(), QVector() << T_FOO << T_BAR << T_BAZ); } -void tst_QList::toVectorInt() const +void tst_QList::toVectorOptimal() const { - toVector(); + const int liveCount = Optimal::getLiveCount(); + toVector(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::toVectorMovable() const @@ -1367,9 +1492,11 @@ void tst_QList::value() const QCOMPARE(list.value(3, defaultT), defaultT); } -void tst_QList::valueInt() const +void tst_QList::valueOptimal() const { - value(); + const int liveCount = Optimal::getLiveCount(); + value(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::valueMovable() const @@ -1419,9 +1546,11 @@ void tst_QList::testOperators() const QCOMPARE(list[list.size() - 1], T_CAT); } -void tst_QList::testOperatorsInt() const +void tst_QList::testOperatorsOptimal() const { - testOperators(); + const int liveCount = Optimal::getLiveCount(); + testOperators(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::testOperatorsMovable() const @@ -1478,9 +1607,11 @@ void tst_QList::testSTLIterators() const QCOMPARE(*it, T_FOO); } -void tst_QList::testSTLIteratorsInt() const +void tst_QList::testSTLIteratorsOptimal() const { - testSTLIterators(); + const int liveCount = Optimal::getLiveCount(); + testSTLIterators(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::testSTLIteratorsMovable() const @@ -1525,9 +1656,11 @@ void tst_QList::constSharedNull() const QVERIFY(!list2.isDetached()); } -void tst_QList::constSharedNullInt() const +void tst_QList::constSharedNullOptimal() const { - constSharedNull(); + const int liveCount = Optimal::getLiveCount(); + constSharedNull(); + QCOMPARE(liveCount, Optimal::getLiveCount()); } void tst_QList::constSharedNullMovable() const -- cgit v1.2.3