summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2021-12-07 17:46:26 +0100
committerMarc Mutz <marc.mutz@qt.io>2021-12-08 16:39:27 +0000
commitd4a88e4ea4dd0d24c9c43553dd4c48a79635803c (patch)
tree2c31d0b6c2203a718e0f247e7d09baba046d5661 /tests/auto/corelib/tools
parent0f88e79ed80aaf3c02def55c6d507dde17eada60 (diff)
QVarLengthArray: fix size update on failed append()
If the in-place constructor throws, the old code had already updated the container's size(). Fix by delaying the update to after the in-place construction. [ChangeLog][QtCore][QVarLengthArray] Fixed a bug whereby a failed append() would leave the container with an inconsistent size(). Pick-to: 6.2 5.15 Change-Id: Ief1e668d945149bd8ba96c8af1398baaa7876880 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'tests/auto/corelib/tools')
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
index 3631f4f977..4944da71a9 100644
--- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
+++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
@@ -30,6 +30,7 @@
#include <qvarlengtharray.h>
#include <qvariant.h>
#include <qscopeguard.h>
+#include <qscopedvaluerollback.h>
#include <memory>
@@ -85,6 +86,7 @@ private slots:
void removeLast();
void oldTests();
void appendCausingRealloc();
+ void appendIsStronglyExceptionSafe();
void resize();
void realloc();
void iterators();
@@ -402,6 +404,49 @@ void tst_QVarLengthArray::appendCausingRealloc()
d.append(i);
}
+void tst_QVarLengthArray::appendIsStronglyExceptionSafe()
+{
+#ifdef QT_NO_EXCEPTIONS
+ QSKIP("This test requires exception support enabled in the compiler.");
+#else
+ static bool throwOnCopyNow = false;
+ static bool throwOnMoveNow = false;
+ struct Thrower {
+ Thrower() = default;
+ Thrower(const Thrower &)
+ {
+ if (throwOnCopyNow)
+ throw 1;
+ }
+ Thrower &operator=(const Thrower &) = default;
+ Thrower(Thrower &&)
+ {
+ if (throwOnMoveNow)
+ throw 1;
+ }
+ Thrower &operator=(Thrower &&) = default;
+ ~Thrower() = default;
+ };
+
+ {
+ // ### TODO: QVLA isn't exception-safe when throwing during reallocation,
+ // ### so check with size() < capacity() for now
+ QVarLengthArray<Thrower, 2> vla(1);
+ {
+ Thrower t;
+ const QScopedValueRollback rb(throwOnCopyNow, true);
+ QVERIFY_THROWS_EXCEPTION(int, vla.push_back(t));
+ QCOMPARE(vla.size(), 1);
+ }
+ {
+ const QScopedValueRollback rb(throwOnMoveNow, true);
+ QVERIFY_THROWS_EXCEPTION(int, vla.push_back({}));
+ QCOMPARE(vla.size(), 1);
+ }
+ }
+#endif
+}
+
void tst_QVarLengthArray::resize()
{
// Empty Movable