summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-08-23 13:47:21 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-08-23 15:22:31 (GMT)
commit6d8c9c3fddbe1fe0736a015164d5713d49a296d8 (patch)
tree15d4052da17981be9c976efdc96de097f98aab77
parenta2f83283a64460ca26530321f8eb64f3ddfe4c8b (diff)
downloadQt-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.h20
-rw-r--r--tests/auto/collections/tst_collections.cpp42
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
}