QMetaType: Avoid instantiating QMetaType in Q_DECLARE_METATYPE

Having a call to QMetaType::fromType in struct QMetaTypeId causes issues
if Q_DECLARE_TYPEINFO is used later, as it will already cause an
instantiation of QTypeInfo. Instead, use QtPrivate::typenameHelper to
obtain the name. We cannot use QMetaTypeForType::getName, as that would
cause similarissues with QMetaTypeId2. However, QMetaTypeId2 is only
used for builtin metatypes, which do not use Q_DECLARE_METATYPE. And
even if a user would use Q_DECLARE_METATYPE with them, the worst that
happens is a superfluous type normalization.

Fixes: QTBUG-94124
Change-Id: Ie4a993411214fd009a604de44306131c647095eb
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Fabian Kosmale 2021-06-01 11:43:29 +02:00
parent cafdb8d3ee
commit f6f7d22c6c

View File

@ -1349,12 +1349,6 @@ struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
} QT_END_NAMESPACE \
/**/
template <typename T>
int qRegisterMetatypeIndirection()
{
return qRegisterNormalizedMetaType<T>(QMetaType::fromType<T>().name());
}
#ifndef Q_MOC_RUN
#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
#define Q_DECLARE_METATYPE_IMPL(TYPE) \
@ -1368,11 +1362,12 @@ int qRegisterMetatypeIndirection()
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (const int id = metatype_id.loadAcquire()) \
return id; \
const auto mt = QMetaType::fromType<TYPE>(); \
if (QByteArrayView(mt.name()) == (#TYPE)) { \
qRegisterMetatypeIndirection<TYPE>(); \
metatype_id.storeRelease(mt.id()); \
return mt.id(); \
constexpr auto arr = QtPrivate::typenameHelper<TYPE>(); \
auto name = arr.data(); \
if (QByteArrayView(name) == (#TYPE)) { \
const int id = qRegisterNormalizedMetaType<TYPE>(name); \
metatype_id.storeRelease(id); \
return id; \
} \
const int newId = qRegisterMetaType< TYPE >(#TYPE); \
metatype_id.storeRelease(newId); \
@ -1576,7 +1571,6 @@ QT_END_NAMESPACE
QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
QT_BEGIN_NAMESPACE
@ -2465,4 +2459,6 @@ constexpr const QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
#endif // QMETATYPE_H