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
Pick-to: 6.3 6.2
Change-Id: I5139da58d99e9491a582ff2cb2f817cd96952044
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2022-03-15 16:25:29 +01:00
parent 73d0174f50
commit 9f8da21239
3 changed files with 18 additions and 1 deletions

View File

@ -3617,6 +3617,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!");
}
/*!

View File

@ -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;

View File

@ -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;