tst_qmetatype: fix memleaks
We didn't delete the new'ed up QMetaTypeInterfaces, causing asan to complain. Fix by storing them in strong references alongside their users in a statically-allocated container. We use shared_ptr to hold them, because QMetaTypeInterface doesn't have a virtual destructor, so deleting objects of the TypeInfo types (plural!) derived from QMetaTypeInterface though a pointer to the base class is UB. The shared_ptr constructor, however, is templated, so it stores the correct call (~TypeInfo()) in its type-erased deleter. We can't use std::make_shared(), because that doesn't support aggregate initialization until C++20, so we manually new up the TypeInfos. 5.15 is not affected. Pick-to: 6.3 6.2 Change-Id: Ic7ec88c34e02a9e0dd3421848c0c0885f4756702 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
This commit is contained in:
parent
b6239f70f5
commit
58058794b1
@ -36,6 +36,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
Q_DECLARE_METATYPE(QMetaType::Type)
|
||||
|
||||
@ -237,6 +238,12 @@ struct GenericPODType : BaseGenericType
|
||||
QByteArray podData;
|
||||
};
|
||||
|
||||
// The order of the next two statics matters!
|
||||
//
|
||||
// need to use shared_ptr, for its template ctor, since QMetaTypeInterface isn't polymorphic,
|
||||
// but the test derives from it
|
||||
static std::vector<std::shared_ptr<QtPrivate::QMetaTypeInterface>> s_metaTypeInterfaces;
|
||||
|
||||
using RegisteredType = QPair<std::shared_ptr<BaseGenericType>, std::shared_ptr<QMetaObject>>;
|
||||
static QHash<int, RegisteredType> s_managedTypes;
|
||||
|
||||
@ -326,7 +333,7 @@ void tst_QMetaType::registerGadget(const char *name, const QList<GadgetPropertyT
|
||||
QMetaObject *mo;
|
||||
};
|
||||
|
||||
auto typeInfo = new TypeInfo {
|
||||
auto typeInfo = s_metaTypeInterfaces.emplace_back(new TypeInfo {
|
||||
{
|
||||
0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0,
|
||||
[](const QtPrivate::QMetaTypeInterface *self) -> const QMetaObject * {
|
||||
@ -345,7 +352,7 @@ void tst_QMetaType::registerGadget(const char *name, const QList<GadgetPropertyT
|
||||
nullptr
|
||||
},
|
||||
meta
|
||||
};
|
||||
}).get();
|
||||
QMetaType gadgetMetaType(typeInfo);
|
||||
dynamicGadgetProperties->m_metatype = gadgetMetaType;
|
||||
int gadgetTypeId = QMetaType(typeInfo).id();
|
||||
@ -1241,7 +1248,7 @@ void tst_QMetaType::typedConstruct()
|
||||
dynamicGadgetProperties->podData = myPodTesData;
|
||||
const auto flags = QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
|
||||
using TypeInfo = QtPrivate::QMetaTypeInterface;
|
||||
auto typeInfo = new TypeInfo {
|
||||
auto typeInfo = s_metaTypeInterfaces.emplace_back(new TypeInfo {
|
||||
0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0, nullptr, podTypeName,
|
||||
[](const TypeInfo *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); },
|
||||
[](const TypeInfo *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
|
||||
@ -1253,7 +1260,7 @@ void tst_QMetaType::typedConstruct()
|
||||
GadgetSaveOperator,
|
||||
GadgetLoadOperator,
|
||||
nullptr
|
||||
};
|
||||
}).get();
|
||||
QMetaType metatype(typeInfo);
|
||||
dynamicGadgetProperties->m_metatype = metatype;
|
||||
int podTypeId = metatype.id();
|
||||
|
Loading…
x
Reference in New Issue
Block a user