aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmllistmodel
diff options
context:
space:
mode:
authorJaeyoon Jung <jaeyoon.jung@lge.com>2021-09-01 18:47:08 +0900
committerJaeyoon Jung <jaeyoon.jung@lge.com>2021-09-02 17:20:42 +0900
commit219ca3bf2be65fb4f1741bdc7b53d6dc4a41dd31 (patch)
treec83ed8d25b3ad51215b2af1f7a4671e3fd30842e /tests/auto/qml/qqmllistmodel
parent2e04ba299437296edcb42f9366d73c812b70373f (diff)
QQmlListModel: Fix C++ owned object getting destroyed
If an object is explicitly set as C++ owned, it should not be turned to destructible in any case. explicitIndestructibleSet flag is used for that and thus it should not be unset in any case. This fixes an issue where a C++ owned object could be destroyed by GC when it is added to a ListModel. An object is supposed to be set as destructible implicitly when it is used as a return value from JS unless explicitIndestructibleSet is set. Fixes: QTBUG-96167 Pick-to: 6.2 Change-Id: Iad06847e56e29dd1b20146be108d7f747d8474dc Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Jaeyoon Jung <jaeyoon.jung@lge.com>
Diffstat (limited to 'tests/auto/qml/qqmllistmodel')
-rw-r--r--tests/auto/qml/qqmllistmodel/data/objectOwnership.qml27
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp35
2 files changed, 62 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmllistmodel/data/objectOwnership.qml b/tests/auto/qml/qqmllistmodel/data/objectOwnership.qml
new file mode 100644
index 0000000000..0ebb29d75b
--- /dev/null
+++ b/tests/auto/qml/qqmllistmodel/data/objectOwnership.qml
@@ -0,0 +1,27 @@
+import QtQuick
+
+ListView {
+ id: root
+ width: 100
+ height: 100
+
+ delegate: Component {
+ Item {
+ property Item myItem: refItem
+ }
+ }
+
+ model: ListModel {
+ id: listModel
+ objectName: "listModel"
+
+ function addItem() {
+ append({"refItem": cppOwnedItem});
+ }
+ }
+
+ function checkItem() {
+ root.currentIndex = 0;
+ currentItem.myItem.dummy();
+ }
+}
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index 7f94180274..fae2b8da63 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -137,6 +137,7 @@ private slots:
void emptyStringNotUndefined();
void listElementWithTemplateString();
void destroyComponentObject();
+ void objectOwnershipFlip();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1882,6 +1883,40 @@ void tst_qqmllistmodel::destroyComponentObject()
QCOMPARE(list->count(), 1);
}
+// Used for objectOwnershipFlip
+class TestItem : public QQuickItem
+{
+ Q_OBJECT
+public:
+ // To trigger QQmlData::setImplicitDestructible through QV4::CallArgument::toValue
+ Q_INVOKABLE TestItem* dummy() { return this; }
+};
+
+void tst_qqmllistmodel::objectOwnershipFlip()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("objectOwnership.qml"));
+ QVERIFY(!component.isError());
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(!root.isNull());
+ QQmlListModel *model = root->findChild<QQmlListModel*>("listModel");
+ QVERIFY(model != nullptr);
+
+ QScopedPointer<TestItem> item(new TestItem());
+ item->setObjectName("cppOwnedItem");
+ QJSEngine::setObjectOwnership(item.data(), QJSEngine::CppOwnership);
+ QCOMPARE(QJSEngine::objectOwnership(item.data()), QJSEngine::CppOwnership);
+
+ engine.rootContext()->setContextProperty("cppOwnedItem", item.data());
+
+ QMetaObject::invokeMethod(model, "addItem");
+ QCOMPARE(model->count(), 1);
+
+ QMetaObject::invokeMethod(root.data(), "checkItem");
+
+ QCOMPARE(QJSEngine::objectOwnership(item.data()), QJSEngine::CppOwnership);
+}
+
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"