summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlist.h
diff options
context:
space:
mode:
authormread <qt-info@nokia.com>2009-09-08 14:36:38 +0100
committermread <qt-info@nokia.com>2009-09-08 14:59:18 +0100
commite31047fd3afd10e7d2d457b1a1bd4ee9bd48979a (patch)
treeb1b21853b7fc6932c985d36fce27d3e3259e3194 /src/corelib/tools/qlist.h
parent97fad21de75f2753cc9804f5924074b7b0d99262 (diff)
exception safety fix for QList::operator+= (const QList&)
The refactoring of current++ and src++ out of the new line makes the code easier to understand but it also seems to be significant at least in the ::isComplex case. I suspect that the ordering increment operations vs throw from new is not well defined, or not implemented as you might hope (with the ++ happening very last). The changes in the catch blocks mean that it deletes the created objects, rather than trying with the first failed object. The test code has been updated with a +=(Container) test, and to force testing of both static and moveable types. Reviewed-by: Harald Fernengel
Diffstat (limited to 'src/corelib/tools/qlist.h')
-rw-r--r--src/corelib/tools/qlist.h19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index c2bdbeee91..f316feca65 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -367,21 +367,26 @@ Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src)
if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
QT_TRY {
while(current != to) {
- (current++)->v = new T(*reinterpret_cast<T*>((src++)->v));
+ current->v = new T(*reinterpret_cast<T*>(src->v));
+ ++current;
+ ++src;
}
} QT_CATCH(...) {
- while (current != from)
- delete reinterpret_cast<T*>(current--);
+ while (current-- != from)
+ delete reinterpret_cast<T*>(current->v);
QT_RETHROW;
}
} else if (QTypeInfo<T>::isComplex) {
QT_TRY {
- while(current != to)
- new (current++) T(*reinterpret_cast<T*>(src++));
+ while(current != to) {
+ new (current) T(*reinterpret_cast<T*>(src));
+ ++current;
+ ++src;
+ }
} QT_CATCH(...) {
- while (current != from)
- (reinterpret_cast<T*>(current--))->~T();
+ while (current-- != from)
+ (reinterpret_cast<T*>(current))->~T();
QT_RETHROW;
}
} else {