summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-10-25 08:41:37 +0200
committerPaul Lemire <paul.lemire@kdab.com>2019-10-28 08:13:45 +0200
commitfe790f1537d17fca586a2c6ea7f57c02cfab1b88 (patch)
tree16ca2da51f5ab317d2e4561e16dd395b358dd222 /src
parent048ca3b1c5227de50fc755270dc316767b465936 (diff)
QNode::updateNode: ensure postConstructorInit of node is called
When a QNode subclass is created doing Subclass(parent) with parent != nullptr QNodePrivate::_q_postContrustorInit is called through a queued invocation due to the fact that the QNode ctor is called before the subclass ctor is (and we need the class to be fully constructed to do proper initialization). When adding a QNode subclass created as described above, and immediately referencing it as a property of another QNode, we can end up in cases where the backend gets aware of the node being referenced in the relationship and tries to create its backend. Unfortunately due to the queued invocation of _q_postConstructorInit, the frontend node has yet to be fully initialized, resulting in the creation of the backend node to assert/crash. Therefore, when updateNode is called (whenever a subnode is referenced in a relationship) we now ensure that postConstructorInit gets (or has already been) called. Change-Id: Iea6e0b5a59c676f5db2946bec2f8c345accc32b0 Task-number: QTBUG-79350 Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/nodes/qnode.cpp5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index cfe83f4db..739b46cfe 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -683,6 +683,11 @@ void QNodePrivate::update()
void QNodePrivate::updateNode(QNode *node, const char *property, ChangeFlag change)
{
if (m_changeArbiter) {
+ // Ensure node has its postConstructorInit called if we reach this
+ // point, we could otherwise endup referencing a node that has yet
+ // to be created in the backend
+ QNodePrivate::get(node)->_q_ensureBackendNodeCreated();
+
Q_Q(QNode);
m_changeArbiter->addDirtyFrontEndNode(q, node, property, change);
}