summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2021-12-22 09:16:36 +0100
committerMarc Mutz <marc.mutz@qt.io>2021-12-22 13:41:30 +0100
commit58058794b1379f153d28d844d5220298f21bcf96 (patch)
tree2e729cb9546cd54236ae038aecf617497c1da9aa /tests/auto
parentb6239f70f57961cceec5f0c5f56e3f94b1d5a92a (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.cpp15
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();