path: root/src/corelib/kernel/qmetatype.cpp
diff options
authorOlivier Goffart <>2015-08-14 16:09:21 +0200
committerOlivier Goffart (Woboq GmbH) <>2015-08-26 06:46:05 +0000
commit5a500100581f17f057f1958f956b2ddaf7048ecf (patch)
tree1eb737e6fd38d0d074f5457084e79c680429b5b5 /src/corelib/kernel/qmetatype.cpp
parent418824dc691fd7fe2fede6b9566f0c4db098e772 (diff)
Be more tolerant with multiple differerent metatype registrations
There is a qFatal in qmetatype.cpp that checks that the flags are the same. There is a binary compatibility break because if any cause build with Qt 5.5 is loaded, this qFatal will quit the application, due to the change in commit 54a09a41885e65fea4ca20d0e3d90d8f4e9e80c5: Type flags for type 'QtMetaTypePrivate::QPairVariantInterfaceImpl' [1034] don't match. Previously registered TypeFlags(0x103), now registering TypeFlags(0x107). This is an ODR break, which means that your application depends on a C++ undefined behavior. This is a false positive since it is an internal type, the MovableType in QMetaType is only being used for performance reason, it is perfectly fine to change it. This commit changes the qFatal to complain only about flags that could only be caused by a binary incompatible change. Change-Id: I87b9bf8cf54b6c7f4b1277d411ce5107642435ab Reviewed-by: Thiago Macieira <>
Diffstat (limited to 'src/corelib/kernel/qmetatype.cpp')
1 files changed, 8 insertions, 17 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 3906cdc036..01e2542dfa 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -1081,25 +1081,16 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
normalizedTypeName.constData(), idx, previousSize, size);
- // Do not compare types higher than 0x100:
- // Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem
- // Ignore IsGadget as it was added in Qt 5.5
- // Ignore all the future flags as well
- if ((previousFlags ^ flags) & 0xff) {
- const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType;
+ // these flags cannot change in a binary compatible way:
+ const int binaryCompatibilityFlag = PointerToQObject | IsEnumeration | SharedPointerToQObject
+ | WeakPointerToQObject | TrackingPointerToQObject;
+ if ((previousFlags ^ flags) & binaryCompatibilityFlag) {
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";
- 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());
+ "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). ";
+ qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags));
return idx;