diff options
author | Marc Mutz <marc.mutz@qt.io> | 2021-12-22 09:16:36 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2021-12-22 13:41:30 +0100 |
commit | 58058794b1379f153d28d844d5220298f21bcf96 (patch) | |
tree | 2e729cb9546cd54236ae038aecf617497c1da9aa /tests/auto | |
parent | b6239f70f57961cceec5f0c5f56e3f94b1d5a92a (diff) |
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>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 15 |
1 files 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 d4ea231a7e..740dcbc9be 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -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(); |