diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-06-05 20:10:56 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-06-07 13:14:00 +0200 |
commit | f6fb118c943ca4e54509b3c4c8aaafcdbb88f031 (patch) | |
tree | df0b007b4c3cafdda59b4c8d02b7db2f93caf423 /tests/auto/corelib | |
parent | 0ebe5c9ef617b3bb889d159958bc634f4959bed0 (diff) |
QProperty: Do not involve semi-destroyed QObjects in bindings
Once we're in ~QObject, only methods of QObject are still valid.
Notably, no setter of any derived class is still valid. Thus, to be safe
we must no longer react to binding changes of those properties. To
ensure that this happens for QObjectCompatProperty properties, we
explicitly clear the binding storage.
Fixes a particles3d example crash.
Change-Id: I10d2bfa5e96621ce039d751cffaf3ac41893623e
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r-- | tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp index d1dc0ceacf..735d45da2a 100644 --- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -57,6 +57,7 @@ private slots: void basicDependencies(); void multipleDependencies(); void bindingWithDeletedDependency(); + void dependencyChangeDuringDestruction(); void recursiveDependency(); void bindingAfterUse(); void bindingFunctionDtorCalled(); @@ -199,6 +200,35 @@ void tst_QProperty::bindingWithDeletedDependency() QCOMPARE(propertySelector.value(), staticProperty.value()); } +class ChangeDuringDtorTester : public QObject +{ + Q_OBJECT + Q_PROPERTY(int prop READ prop WRITE setProp BINDABLE bindableProp) + +public: + void setProp(int i) { m_prop = i;} + int prop() const { return m_prop; } + QBindable<int> bindableProp() { return &m_prop; } +private: + Q_OBJECT_COMPAT_PROPERTY(ChangeDuringDtorTester, int, m_prop, &ChangeDuringDtorTester::setProp) +}; + +void tst_QProperty::dependencyChangeDuringDestruction() +{ + auto tester = std::make_unique<ChangeDuringDtorTester>(); + QProperty<int> iprop {42}; + tester->bindableProp().setBinding(Qt::makePropertyBinding(iprop)); + QObject::connect(tester.get(), &QObject::destroyed, [&](){ + iprop = 12; + }); + bool failed = false; + auto handler = tester->bindableProp().onValueChanged([&](){ + failed = true; + }); + tester.reset(); + QVERIFY(!failed); +} + void tst_QProperty::recursiveDependency() { QProperty<int> first(1); |