From 58058794b1379f153d28d844d5220298f21bcf96 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 22 Dec 2021 09:16:36 +0100 Subject: [PATCH] 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 Reviewed-by: Andrei Golubev --- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index d4ea231a7ed..740dcbc9bef 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -36,6 +36,7 @@ #include #include +#include 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> s_metaTypeInterfaces; + using RegisteredType = QPair, std::shared_ptr>; static QHash s_managedTypes; @@ -326,7 +333,7 @@ void tst_QMetaType::registerGadget(const char *name, const QList const QMetaObject * { @@ -345,7 +352,7 @@ void tst_QMetaType::registerGadget(const char *name, const QListm_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();