Remove the name cache from QMetaType::typeName

It was unnecessary, since we only cached the static types, which are all
generated by the macro anyway. The way it was implemented, this produced
data races that are strictly-speaking UB, even if all the threads were
writing the same values to the same data locations.

This commit changes a little the code to simplify, since we're changing
those lines anyway.

Task-number: QTBUG-58851
Change-Id: Idc5061f7145940f987dffffd14a30047846e3113
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Thiago Macieira 2017-02-13 16:36:49 -08:00
parent 7dff4b921b
commit fb376e0fcc

View File

@ -834,38 +834,27 @@ void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
const char *QMetaType::typeName(int typeId)
{
const uint type = typeId;
// In theory it can be filled during compilation time, but for some reason template code
// that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably
// it is not worth of it.
static const char *namesCache[QMetaType::HighestInternalId + 1];
const char *result;
if (type <= QMetaType::HighestInternalId && ((result = namesCache[type])))
return result;
#define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
case QMetaType::MetaTypeName: result = #RealName; break;
case QMetaType::MetaTypeName: return #RealName; break;
switch (QMetaType::Type(type)) {
QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER)
case QMetaType::UnknownType:
case QMetaType::User:
break;
}
default: {
if (Q_UNLIKELY(type < QMetaType::User)) {
return 0; // It can happen when someone cast int to QVariant::Type, we should not crash...
} else {
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
? ct->at(type - QMetaType::User).typeName.constData()
: 0;
}
}
if (Q_UNLIKELY(type < QMetaType::User)) {
return nullptr; // It can happen when someone cast int to QVariant::Type, we should not crash...
}
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
? ct->at(type - QMetaType::User).typeName.constData()
: nullptr;
#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
Q_ASSERT(type <= QMetaType::HighestInternalId);
namesCache[type] = result;
return result;
}
/*