summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-06-05 20:10:56 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2021-06-07 13:14:00 +0200
commitf6fb118c943ca4e54509b3c4c8aaafcdbb88f031 (patch)
treedf0b007b4c3cafdda59b4c8d02b7db2f93caf423 /tests/auto/corelib
parent0ebe5c9ef617b3bb889d159958bc634f4959bed0 (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.cpp30
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);