QCborValue: fix the move-assignment operator

The double-swap technique I used was flawed and broke on
self-assignment. What I had meant to use was the move-and-swap
technique. Thanks to Peppe for pointing it out.

This also fixes a compiler bug in the Green Hills compiler. It was
finding the wrong "swap" function in qSwap:

    using std::swap;
    swap(value1, value2);

It's supposed to find swap(QCborValue &, QCborValue &) due to argument-
dependent lookup. It's instead finding std::swap<QCborValue>, which
recurses.

Fixes: QTBUG-83390
Change-Id: Ibdc95e9af7bd456a94ecfffd1603e1bee90cd107
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
Thiago Macieira 2020-04-08 12:13:55 -03:00
parent 1ec350e35f
commit bfb9b02d3b
2 changed files with 14 additions and 3 deletions

View File

@ -188,9 +188,8 @@ public:
QCborValue &operator=(const QCborValue &other); QCborValue &operator=(const QCborValue &other);
QCborValue &operator=(QCborValue &&other) noexcept QCborValue &operator=(QCborValue &&other) noexcept
{ {
QCborValue tmp; QCborValue tmp(std::move(other));
qSwap(*this, tmp); swap(tmp);
qSwap(other, *this);
return *this; return *this;
} }

View File

@ -385,9 +385,21 @@ void tst_QCborValue::copyCompare()
{ {
QFETCH(QCborValue, v); QFETCH(QCborValue, v);
QCborValue other = v; QCborValue other = v;
// self-moving
v = std::move(v);
QCOMPARE(v, other); // make sure it's still valid
// moving
v = std::move(other);
other = std::move(v);
// normal copying
other = v;
other = v; other = v;
v = other; v = other;
QCOMPARE(v.compare(other), 0); QCOMPARE(v.compare(other), 0);
QCOMPARE(v, other); QCOMPARE(v, other);
QVERIFY(!(v != other)); QVERIFY(!(v != other));