diff options
author | João Abecasis <joao.abecasis@nokia.com> | 2012-01-30 14:50:04 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-07 09:47:51 +0100 |
commit | 5a92dd612472378ec329d380fdc8fe609478b06c (patch) | |
tree | 3f48a2970f9a0d7f81b09e3c91035a250ee0c05c /tests | |
parent | b8cf1d6bdcaefaa610014a742808af3ab2c6fe06 (diff) |
Detect incompatibilities in repeated type registration
QMetaType used to register a typeName and factory functions for
creation/destruction of objects. While it would be possible for a single
type name to be registered matching different actual types and memory
layouts, there was little that could be done about it.
Now that QMetaType is tracking type information with a direct impact on
data layout and ABI (size and type flags) it is important that we check
and detect binary incompatibilities as early as possible.
[Such incompatibilities could arise from type name re-use (technically,
ODR violations) or, more commonly, as version mismatch between different
shared libraries or plugins.]
Only type size and flags are checked as function pointers to inline and
template or otherwise non-exported functions could trivially differ
across translation units and shared libraries.
When registering typedef types, a check is made to ensure the same name
doesn't get registered as different types.
Change-Id: I8211c3de75d4854ce8fafdb620d3a931c206e0c3
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index ca2964d3e2..f90e7f463f 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -85,6 +85,7 @@ private slots: void constructCopy_data(); void constructCopy(); void typedefs(); + void registerType(); void isRegistered_data(); void isRegistered(); void registerStreamBuiltin(); @@ -828,6 +829,44 @@ void tst_QMetaType::typedefs() QCOMPARE(QMetaType::type("WhityDouble"), ::qMetaTypeId<WhityDouble>()); } +void tst_QMetaType::registerType() +{ + // Built-in + QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString)); + QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString)); + + // Custom + int fooId = qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo"); + QVERIFY(fooId >= int(QMetaType::User)); + QCOMPARE(qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo"), fooId); + + int movableId = qRegisterMetaType<CustomMovable>("CustomMovable"); + QVERIFY(movableId >= int(QMetaType::User)); + QCOMPARE(qRegisterMetaType<CustomMovable>("CustomMovable"), movableId); + + // Alias to built-in + typedef QString MyString; + + QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString)); + QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString)); + + QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString)); + + // Alias to custom type + typedef CustomMovable MyMovable; + typedef TestSpace::Foo MyFoo; + + QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId); + QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId); + + QCOMPARE(QMetaType::type("MyMovable"), movableId); + + QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId); + QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId); + + QCOMPARE(QMetaType::type("MyFoo"), fooId); +} + class IsRegisteredDummyType { }; void tst_QMetaType::isRegistered_data() |