From 2fb17f3feefcca8862f6f908fe81957f34096c00 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 17 Apr 2013 13:44:40 +0200 Subject: [PATCH] Fix crash in repeater when model gets deleted Task-number: QTBUG-200461 Change-Id: Ia8e48668960ac005cf773bf6f53da40f1c753b9b Reviewed-by: Alan Alpert --- src/quick/items/qquickrepeater.cpp | 4 +- src/quick/items/qquickrepeater_p_p.h | 2 +- .../quick/qquickrepeater/data/visualitemmodel.qml | 23 ++++++++++++++++++++ .../quick/qquickrepeater/tst_qquickrepeater.cpp | 12 ++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 tests/auto/quick/qquickrepeater/data/visualitemmodel.qml diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 35e37d1..bf6d3c4 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -217,7 +217,7 @@ void QQuickRepeater::setModel(const QVariant &model) d->model = new QQmlDelegateModel(qmlContext(this)); d->ownModel = true; if (isComponentComplete()) - static_cast(d->model)->componentComplete(); + static_cast(d->model.data())->componentComplete(); } if (QQmlDelegateModel *dataModel = qobject_cast(d->model)) dataModel->setModel(model); @@ -329,7 +329,7 @@ void QQuickRepeater::componentComplete() { Q_D(QQuickRepeater); if (d->model && d->ownModel) - static_cast(d->model)->componentComplete(); + static_cast(d->model.data())->componentComplete(); QQuickItem::componentComplete(); regenerate(); if (d->model && d->model->count()) diff --git a/src/quick/items/qquickrepeater_p_p.h b/src/quick/items/qquickrepeater_p_p.h index f220eb4..a642f64 100644 --- a/src/quick/items/qquickrepeater_p_p.h +++ b/src/quick/items/qquickrepeater_p_p.h @@ -73,7 +73,7 @@ public: private: void createItems(); - QQmlInstanceModel *model; + QPointer model; QVariant dataSource; QQmlGuard dataSourceAsObject; bool ownModel : 1; diff --git a/tests/auto/quick/qquickrepeater/data/visualitemmodel.qml b/tests/auto/quick/qquickrepeater/data/visualitemmodel.qml new file mode 100644 index 0000000..b1b7b97 --- /dev/null +++ b/tests/auto/quick/qquickrepeater/data/visualitemmodel.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Rectangle { + width: 360 + height: 360 + + VisualItemModel { + id: visItemModel + Rectangle { + width: 20 + height: 20 + color: "red" + } + } + + Column { + anchors.fill: parent + Repeater { + model: visItemModel + } + } +} + diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp index 582503f..9fb76f9 100644 --- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp +++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp @@ -78,6 +78,7 @@ private slots: void asynchronous(); void initParent(); void dynamicModelCrash(); + void visualItemModelCrash(); }; class TestObject : public QObject @@ -732,6 +733,17 @@ void tst_QQuickRepeater::dynamicModelCrash() QVERIFY(qvariant_cast(repeater->model()) == 0); } +void tst_QQuickRepeater::visualItemModelCrash() +{ + // This used to crash because the model would get + // deleted before the repeater, leading to double-deletion + // of the items. + QQuickView *window = createView(); + window->setSource(testFileUrl("visualitemmodel.qml")); + qApp->processEvents(); + delete window; +} + QTEST_MAIN(tst_QQuickRepeater) #include "tst_qquickrepeater.moc" -- 1.7.2.5