From 98b77f9faa14822479deb20cd6fe0ce4fe9b56da Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 25 Jul 2012 09:08:33 +0200 Subject: QMetaType: remember whether a type was registered with Q_DECLARE_METATYPE There are two ways to register a type: using Q_DECLARE_METATYPE(T) and using qRegisterMetaType("T"). Doing one thing in one translation unit and another thing in another TU constitutes an ODR violation, because the value of QMetaTypeId::Defined will differ in the two TUs. By adding the information whether a type was declared with Q_DECLARE_METATYPE to the typeFlags(), such a use will trigger the existing binary-incompatibility failure that checks for equality of the incoming type flags with the stored ones (if any). I had to encode the type as a defaulted function argument in order to avoid the linker merging instantiations of the function templates and therefore rendering the detection moot. Change-Id: I82017caf300458b411cc8ac2f6653536fac64117 Reviewed-by: Lars Knoll --- src/corelib/kernel/qmetatype.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 06d325f383..09c641e4a3 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -252,7 +252,8 @@ public: IsEnumeration = 0x10, SharedPointerToQObject = 0x20, WeakPointerToQObject = 0x40, - TrackingPointerToQObject = 0x80 + TrackingPointerToQObject = 0x80, + WasDeclaredAsMetaType = 0x100 }; Q_DECLARE_FLAGS(TypeFlags, TypeFlag) @@ -563,12 +564,19 @@ namespace QtPrivate { | (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0) }; }; + + template + struct MetaTypeDefinedHelper + { + enum DefinedType { Defined = defined }; + }; } template int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName #ifndef qdoc , T * dummy = 0 + , typename QtPrivate::MetaTypeDefinedHelper::Defined && !QMetaTypeId2::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper::Defined && !QMetaTypeId2::IsBuiltIn>::Defined #endif ) { @@ -580,6 +588,10 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf); QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags::Flags); + + if (defined) + flags |= QMetaType::WasDeclaredAsMetaType; + return QMetaType::registerNormalizedType(normalizedTypeName, QtMetaTypePrivate::QMetaTypeFunctionHelper::Delete, QtMetaTypePrivate::QMetaTypeFunctionHelper::Create, @@ -594,6 +606,7 @@ template int qRegisterMetaType(const char *typeName #ifndef qdoc , T * dummy = 0 + , typename QtPrivate::MetaTypeDefinedHelper::Defined && !QMetaTypeId2::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper::Defined && !QMetaTypeId2::IsBuiltIn>::Defined #endif ) { @@ -602,7 +615,7 @@ int qRegisterMetaType(const char *typeName #else QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName); #endif - return qRegisterNormalizedMetaType(normalizedTypeName, dummy); + return qRegisterNormalizedMetaType(normalizedTypeName, dummy, defined); } #ifndef QT_NO_DATASTREAM -- cgit v1.2.3