diff options
author | Andrei Golubev <andrei.golubev@qt.io> | 2022-06-10 15:06:35 +0200 |
---|---|---|
committer | Andrei Golubev <andrei.golubev@qt.io> | 2022-06-15 09:43:01 +0200 |
commit | 48ae7468afc06d52844badb3f5f41114f67a360f (patch) | |
tree | cc02e5a4df41edd6d49dc068f88a4f643a1e1aab | |
parent | b68aa525883ca9ca8e007de3c5b5177fc49af5f4 (diff) |
Fix QQmlTypePrivate memory leak in qmltc-generated types with extensions
Apparently registering the QQmlTypePrivate for a meta-object is not
good enough. Somehow clang's ASan failed to discover a memory leak but
gcc's ASan did not. After carefully exercising the code and a bit of
debugging, turns out we indeed not release manually created
QQmlTypePrivate objects. Do release the QQmlTypePrivate correctly now
In the process of doing so, remove now-redundant QMetaObject function
parameter
Amends 26179e693717535eeff2e7b2a6ee99dc02dcd8f9
Pick-to: 6.4
Change-Id: Ia0c808cd8a09cf996672bca9953108facfdf5d4e
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/qml/qmltc/qqmltcobjectcreationhelper.cpp | 11 | ||||
-rw-r--r-- | src/qml/qmltc/qqmltcobjectcreationhelper_p.h | 4 | ||||
-rw-r--r-- | tools/qmltc/qmltccompilerpieces.h | 5 |
3 files changed, 8 insertions, 12 deletions
diff --git a/src/qml/qmltc/qqmltcobjectcreationhelper.cpp b/src/qml/qmltc/qqmltcobjectcreationhelper.cpp index 4be6ae0c9f..db8517ca70 100644 --- a/src/qml/qmltc/qqmltcobjectcreationhelper.cpp +++ b/src/qml/qmltc/qqmltcobjectcreationhelper.cpp @@ -10,8 +10,7 @@ QT_BEGIN_NAMESPACE -void qmltcCreateDynamicMetaObject(QObject *object, const QMetaObject *staticMetaObject, - const QmltcTypeData &data) +void qmltcCreateDynamicMetaObject(QObject *object, const QmltcTypeData &data) { // TODO: when/if qmltc-compiled types would be registered via // qmltyperegistrar, instead of creating a dummy QQmlTypePrivate, fetch the @@ -19,9 +18,11 @@ void qmltcCreateDynamicMetaObject(QObject *object, const QMetaObject *staticMeta // along with the meta object, module name and revision. all that should be // available ahead-of-time to qmltc. auto qmlTypePrivate = new QQmlTypePrivate(data.regType); - // place the newly created QQmlTypePrivate into the qml meta data storage so - // that it is properly deleted - QQmlMetaType::registerMetaObjectForType(staticMetaObject, qmlTypePrivate); + + // tie qmlTypePrivate destruction to objects's destruction. the type's + // content is not needed once the associated object is deleted + QObject::connect(object, &QObject::destroyed, + [qmlTypePrivate](QObject *) { qmlTypePrivate->release(); }); // initialize QQmlType::QQmlCppTypeData Q_ASSERT(data.regType == QQmlType::CppType); diff --git a/src/qml/qmltc/qqmltcobjectcreationhelper_p.h b/src/qml/qmltc/qqmltcobjectcreationhelper_p.h index 6f81d5265d..ae4633ac43 100644 --- a/src/qml/qmltc/qqmltcobjectcreationhelper_p.h +++ b/src/qml/qmltc/qqmltcobjectcreationhelper_p.h @@ -118,9 +118,7 @@ struct QmltcTypeData } }; -Q_QML_PRIVATE_EXPORT void qmltcCreateDynamicMetaObject(QObject *object, - const QMetaObject *staticMetaObject, - const QmltcTypeData &data); +Q_QML_PRIVATE_EXPORT void qmltcCreateDynamicMetaObject(QObject *object, const QmltcTypeData &data); QT_END_NAMESPACE diff --git a/tools/qmltc/qmltccompilerpieces.h b/tools/qmltc/qmltccompilerpieces.h index bc423807fb..9afc001b55 100644 --- a/tools/qmltc/qmltccompilerpieces.h +++ b/tools/qmltc/qmltccompilerpieces.h @@ -236,10 +236,7 @@ inline decltype(auto) QmltcCodeGenerator::generate_initCode(QmltcType ¤t, if (hasExtension) { current.init.body << u"{"_s; current.init.body << u"auto cppData = QmltcTypeData(this);"_s; - current.init.body - << QStringLiteral( - "qmltcCreateDynamicMetaObject(this, &%1::staticMetaObject, cppData);") - .arg(type->internalName()); + current.init.body << u"qmltcCreateDynamicMetaObject(this, cppData);"_s; current.init.body << u"}"_s; } |