From 0421769e3672a435963c8c7a0b12df134a3f38cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 3 Jan 2013 11:06:21 +0100 Subject: Ignore WasDeclaredAsMetaType flag during binary check. Nobody should break ODR, but we were living with apps breaking it for at least 8 years. Sure it is an undefined behavior but in many cases it works. I do not think that Qt should enforce usage of a proper C++, it is role of a tool chain. Qt can only indicate that something is going terribly wrong. Make message a bit more verbose. Sometimes the ODR violation is not that easy to fix, therefore a hint is a nice addition. Update documentation of qRegisterMetaType. Change-Id: I61dcccc840eec80a4ed5b8a212a912807d239d8c Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetatype.cpp | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 0d737ac1a3..5b039b4fce 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -646,11 +646,26 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, "size %i, now registering size %i.", normalizedTypeName.constData(), idx, previousSize, size); } + + // Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem + previousFlags |= WasDeclaredAsMetaType; + flags |= WasDeclaredAsMetaType; + if (previousFlags != flags) { - qFatal("QMetaType::registerType: Binary compatibility break " - "-- Type flags for type '%s' [%i] don't match. Previously " - "registered TypeFlags(0x%x), now registering TypeFlags(0x%x).", - normalizedTypeName.constData(), idx, previousFlags, int(flags)); + const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType; + const char *msg = "QMetaType::registerType: Binary compatibility break. " + "\nType flags for type '%s' [%i] don't match. Previously " + "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). " + "This is an ODR break, which means that your application depends on a C++ undefined behavior." + "\nHint: %s"; + QT_PREPEND_NAMESPACE(QByteArray) hint; + if ((previousFlags & maskForTypeInfo) != (flags & maskForTypeInfo)) { + hint += "\nIt seems that the type was registered at least twice in a different translation units, " + "but Q_DECLARE_TYPEINFO is not visible from all the translations unit or different flags were used." + "Remember that Q_DECLARE_TYPEINFO should be declared before QMetaType registration, " + "preferably it should be placed just after the type declaration and before Q_DECLARE_METATYPE"; + } + qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags), hint.constData()); } return idx; @@ -1722,6 +1737,9 @@ const QMetaObject *QMetaType::metaObjectForType(int type) \snippet code/src_corelib_kernel_qmetatype.cpp 9 + \warning This function is useful only for registering an alias (typedef) + for every other use case Q_DECLARE_METATYPE and qMetaTypeId() should be used instead. + \sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(), Q_DECLARE_METATYPE() */ @@ -1767,7 +1785,7 @@ const QMetaObject *QMetaType::metaObjectForType(int type) */ /*! - \fn int qRegisterMetaType(const char *typeName) + \fn int qRegisterMetaType() \relates QMetaType \threadsafe \since 4.2 @@ -1779,6 +1797,14 @@ const QMetaObject *QMetaType::metaObjectForType(int type) \snippet code/src_corelib_kernel_qmetatype.cpp 7 + This function requires that \c{T} is a fully defined type at the point + where the function is called. For pointer types, it also requires that the + pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able + to register pointers to forward declared types. + + After a type has been registered, you can create and destroy + objects of that type dynamically at run-time. + To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is sufficient. To use the type \c T in queued signal and slot connections, \c{qRegisterMetaType()} must be called before the first connection -- cgit v1.2.3