QVariant: Don't crash when doing user-defined conversion to QObject*

The destructor of the ConverterFunctor calls unregisterConverter. If
the instance is static (as it is in qmetatype.h), then this method
can be called after the QGlobalStatic has already been destroyed.

Change-Id: I33b70734cbe09dfa888e887280c349e43ad1b855
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Stephen Kelly 2013-09-05 11:00:25 +02:00 committed by The Qt Project
parent cc594d2064
commit d1a8623ecb
2 changed files with 38 additions and 0 deletions

View File

@ -558,6 +558,8 @@ bool QMetaType::registerConverterFunction(const QtPrivate::AbstractConverterFunc
*/
void QMetaType::unregisterConverterFunction(int from, int to)
{
if (customTypesConversionRegistry.isDestroyed())
return;
customTypesConversionRegistry()->remove(from, to);
}

View File

@ -154,6 +154,7 @@ private slots:
void qvariant_cast_QObject_data();
void qvariant_cast_QObject();
void qvariant_cast_QObject_derived();
void qvariant_cast_QObject_wrapper();
void toLocale();
@ -2235,6 +2236,41 @@ void tst_QVariant::qvariant_cast_QObject_derived()
}
}
struct QObjectWrapper
{
explicit QObjectWrapper(QObject *o = 0) : obj(o) {}
QObject* getObject() const {
return obj;
}
private:
QObject *obj;
};
Q_DECLARE_METATYPE(QObjectWrapper)
struct Converter
{
Converter() {}
QObject* operator()(const QObjectWrapper &f) const
{
return f.getObject();
}
};
void tst_QVariant::qvariant_cast_QObject_wrapper()
{
QMetaType::registerConverter<QObjectWrapper, QObject*>(&QObjectWrapper::getObject);
CustomQObjectDerived *object = new CustomQObjectDerived(this);
QObjectWrapper wrapper(object);
QVariant v = QVariant::fromValue(wrapper);
v.convert(qMetaTypeId<QObject*>());
QCOMPARE(v.value<QObject*>(), object);
}
void tst_QVariant::convertToQUint8() const
{
/* qint8. */