From 6d8c9c3fddbe1fe0736a015164d5713d49a296d8 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 23 Aug 2010 15:47:21 +0200 Subject: Fix assignment of a Q(Explicitly)SharedDataPointer included in the data itself Task-number: related to QTBUG-13079 Reviewed-by: Joao --- src/corelib/tools/qshareddata.h | 20 ++++++++------ tests/auto/collections/tst_collections.cpp | 42 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index 7e9934d..6483c90 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -95,9 +95,10 @@ public: if (o.d != d) { if (o.d) o.d->ref.ref(); - if (d && !d->ref.deref()) - delete d; + T *old = d; d = o.d; + if (old && !old->ref.deref()) + delete old; } return *this; } @@ -105,9 +106,10 @@ public: if (o != d) { if (o) o->ref.ref(); - if (d && !d->ref.deref()) - delete d; + T *old = d; d = o; + if (old && !old->ref.deref()) + delete old; } return *this; } @@ -174,9 +176,10 @@ public: if (o.d != d) { if (o.d) o.d->ref.ref(); - if (d && !d->ref.deref()) - delete d; + T *old = d; d = o.d; + if (old && !old->ref.deref()) + delete old; } return *this; } @@ -184,9 +187,10 @@ public: if (o != d) { if (o) o->ref.ref(); - if (d && !d->ref.deref()) - delete d; + T *old = d; d = o; + if (old && !old->ref.deref()) + delete old; } return *this; } diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp index 8617e02..2dc41aa 100644 --- a/tests/auto/collections/tst_collections.cpp +++ b/tests/auto/collections/tst_collections.cpp @@ -3653,6 +3653,44 @@ bool operator==(const QTBUG13079_Node &a, const QTBUG13079_Node &b) return a.s == b.s && a.children == b.children; } +template class C> +struct QTBUG13079_NodePtr : QSharedData { + C child; + QTBUG13079_NodePtr *next; + QString s; + + ~QTBUG13079_NodePtr() { + child.data(); //play with memory + next = 0; + } +}; +template class C> void QTBUG13079_collectionInsidePtrImpl() +{ + typedef C > Ptr; + { + Ptr nodePtr; + nodePtr = Ptr(new QTBUG13079_NodePtr()); + nodePtr->s = "parent"; + nodePtr->child = Ptr(new QTBUG13079_NodePtr()); + nodePtr->child->s = "child"; + nodePtr = nodePtr->child; + QCOMPARE(nodePtr->s, QString::fromLatin1("child")); + nodePtr = nodePtr->child; + QVERIFY(!nodePtr); + } + { + Ptr nodePtr; + nodePtr = Ptr(new QTBUG13079_NodePtr()); + nodePtr->s = "parent"; + nodePtr->next = new QTBUG13079_NodePtr(); + nodePtr->next->s = "next"; + nodePtr = Ptr(nodePtr->next); + QCOMPARE(nodePtr->s, QString::fromLatin1("next")); + nodePtr = Ptr(nodePtr->next); + QVERIFY(!nodePtr); + } +} + #endif void tst_Collections::QTBUG13079_collectionInsideCollection() @@ -3673,6 +3711,10 @@ void tst_Collections::QTBUG13079_collectionInsideCollection() QTBUG13079_collectionInsideCollectionAssocImpl(); QTBUG13079_collectionInsideCollectionAssocImpl(); + + QTBUG13079_collectionInsidePtrImpl(); + QTBUG13079_collectionInsidePtrImpl(); + QTBUG13079_collectionInsidePtrImpl(); #endif } -- cgit v0.12