diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-08-23 13:47:21 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-08-23 15:22:31 (GMT) |
commit | 6d8c9c3fddbe1fe0736a015164d5713d49a296d8 (patch) | |
tree | 15d4052da17981be9c976efdc96de097f98aab77 | |
parent | a2f83283a64460ca26530321f8eb64f3ddfe4c8b (diff) | |
download | Qt-6d8c9c3fddbe1fe0736a015164d5713d49a296d8.zip Qt-6d8c9c3fddbe1fe0736a015164d5713d49a296d8.tar.gz Qt-6d8c9c3fddbe1fe0736a015164d5713d49a296d8.tar.bz2 |
Fix assignment of a Q(Explicitly)SharedDataPointer included in the data itself
Task-number: related to QTBUG-13079
Reviewed-by: Joao
-rw-r--r-- | src/corelib/tools/qshareddata.h | 20 | ||||
-rw-r--r-- | 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<QSet> &a, const QTBUG13079_Node<QSet> &b) return a.s == b.s && a.children == b.children; } +template<template<class> class C> +struct QTBUG13079_NodePtr : QSharedData { + C<QTBUG13079_NodePtr> child; + QTBUG13079_NodePtr *next; + QString s; + + ~QTBUG13079_NodePtr() { + child.data(); //play with memory + next = 0; + } +}; +template<template<class> class C> void QTBUG13079_collectionInsidePtrImpl() +{ + typedef C<QTBUG13079_NodePtr<C> > Ptr; + { + Ptr nodePtr; + nodePtr = Ptr(new QTBUG13079_NodePtr<C>()); + nodePtr->s = "parent"; + nodePtr->child = Ptr(new QTBUG13079_NodePtr<C>()); + 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<C>()); + nodePtr->s = "parent"; + nodePtr->next = new QTBUG13079_NodePtr<C>(); + 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<QMap>(); QTBUG13079_collectionInsideCollectionAssocImpl<QHash>(); + + QTBUG13079_collectionInsidePtrImpl<QSharedPointer>(); + QTBUG13079_collectionInsidePtrImpl<QExplicitlySharedDataPointer>(); + QTBUG13079_collectionInsidePtrImpl<QSharedDataPointer>(); #endif } |