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 54a09a4188
:
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 <thiago.macieira@intel.com>
This commit is contained in:
parent
418824dc69
commit
5a50010058
@ -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";
|
||||
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());
|
||||
"registered TypeFlags(0x%x), now registering TypeFlags(0x%x). ";
|
||||
|
||||
qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags));
|
||||
}
|
||||
|
||||
return idx;
|
||||
|
Loading…
Reference in New Issue
Block a user