From 16ba55d35b5663841f79b43598aa785ffe41dcfa Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 15 Mar 2022 16:25:29 +0100 Subject: QDateTime: future-proof swap() In Qt 7 32-bit builds, the ShortData will be larger than the d-pointer. So don't swap() the d-pointer, but a) delegate to Data to swap itself and b) swap the ShortData there, adding a static_assert in the .cpp file that triggers when the assumption that ShortData is always at least as large as a pointer is violated. Found while porting away from overly-generic qSwap(), so done that, too. Task-number: QTBUG-97601 Change-Id: I5139da58d99e9491a582ff2cb2f817cd96952044 Reviewed-by: Thiago Macieira (cherry picked from commit 9f8da21239a4d9e22a2d5633920c36af4eb4a6c7) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/time/qdatetime.cpp | 1 + src/corelib/time/qdatetime.h | 5 ++++- tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 6bf29bc0d6..9e58382aef 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -3618,6 +3618,7 @@ QDateTime::QDateTime() noexcept static_assert(sizeof(ShortData) == sizeof(qint64)); static_assert(sizeof(Data) == sizeof(qint64)); #endif + static_assert(sizeof(ShortData) >= sizeof(void*), "oops, Data::swap() is broken!"); } /*! diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h index 80227afde2..c1c67398a3 100644 --- a/src/corelib/time/qdatetime.h +++ b/src/corelib/time/qdatetime.h @@ -267,6 +267,9 @@ class Q_CORE_EXPORT QDateTime Data &operator=(const Data &other); ~Data(); + void swap(Data &other) noexcept + { std::swap(data, other.data); } + bool isShort() const; void detach(); @@ -290,7 +293,7 @@ public: QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QDateTime) QDateTime &operator=(const QDateTime &other) noexcept; - void swap(QDateTime &other) noexcept { qSwap(d.d, other.d.d); } + void swap(QDateTime &other) noexcept { d.swap(other.d); } bool isNull() const; bool isValid() const; diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index 844dead504..79e2823547 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -48,6 +48,7 @@ public Q_SLOTS: private Q_SLOTS: void ctor(); void operator_eq(); + void moveSemantics(); void isNull(); void isValid(); void date(); @@ -332,6 +333,18 @@ void tst_QDateTime::operator_eq() QVERIFY(dt1 == dt2); } +void tst_QDateTime::moveSemantics() +{ + QDateTime dt1{QDate{2004, 3, 24}, QTime{23, 45, 57}, Qt::UTC}; + QDateTime dt2{QDate{2005, 3, 11}, QTime{0, 0}, Qt::UTC}; + QDateTime copy = dt1; + QDateTime moved = std::move(dt1); + QCOMPARE(copy, moved); + copy = dt2; + moved = std::move(dt2); + QCOMPARE(copy, moved); +} + void tst_QDateTime::isNull() { QDateTime dt1; -- cgit v1.2.3