Revert "Fix signed integer overflows in tst_QAtomicInteger"
This reverts commit f647375275. There are
no signed integer overflows in atomics.
For the non-atomic side, unlike the commit being reverted, we fix the
signed integer overflow by removing the "signed" part instead of the
"overflow" part, and use unsigned integer overflows instead.
Change-Id: I53335f845a1345299031fffd176f5ba479163e44
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
bb10
parent
04b619d950
commit
84f8d4961d
|
|
@ -64,6 +64,7 @@ typedef signed char schar;
|
|||
|
||||
typedef TEST_TYPE Type;
|
||||
typedef Type T; // shorthand
|
||||
using U = std::make_unsigned_t<T>;
|
||||
enum {
|
||||
TypeIsUnsigned = Type(-1) > Type(0),
|
||||
TypeIsSigned = !TypeIsUnsigned
|
||||
|
|
@ -289,46 +290,32 @@ void tst_QAtomicIntegerXX::loadAcquireStoreRelease()
|
|||
void tst_QAtomicIntegerXX::refDeref()
|
||||
{
|
||||
QFETCH(LargeInt, value);
|
||||
const bool needToPreventOverflow = TypeIsSigned && value == std::numeric_limits<T>::max();
|
||||
const bool needToPreventUnderflow = TypeIsSigned && value == std::numeric_limits<T>::min();
|
||||
T nextValue = T(value);
|
||||
if (!needToPreventOverflow)
|
||||
++nextValue;
|
||||
T prevValue = T(value);
|
||||
if (!needToPreventUnderflow)
|
||||
--prevValue;
|
||||
|
||||
// We perform arithmetic using the unsigned type U to avoid signed
|
||||
// integer overflows in the non-atomic portion (atomics have well-defined,
|
||||
// two's complement overflow, even signed ones).
|
||||
T nextValue = T(U(value) + 1);
|
||||
T prevValue = T(U(value) - 1);
|
||||
|
||||
QAtomicInteger<T> atomic(value);
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.ref(), (nextValue != 0));
|
||||
QCOMPARE(atomic.loadRelaxed(), nextValue);
|
||||
QCOMPARE(atomic.deref(), (value != 0));
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.deref(), (prevValue != 0));
|
||||
QCOMPARE(atomic.loadRelaxed(), prevValue);
|
||||
QCOMPARE(atomic.ref(), (value != 0));
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(++atomic, nextValue);
|
||||
QCOMPARE(--atomic, T(value));
|
||||
}
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(--atomic, prevValue);
|
||||
QCOMPARE(++atomic, T(value));
|
||||
}
|
||||
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic++, T(value));
|
||||
QCOMPARE(atomic--, nextValue);
|
||||
}
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic--, T(value));
|
||||
QCOMPARE(atomic++, prevValue);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
}
|
||||
|
||||
|
|
@ -431,80 +418,55 @@ void tst_QAtomicIntegerXX::fetchAndAdd()
|
|||
QFETCH(LargeInt, value);
|
||||
QAtomicInteger<T> atomic(value);
|
||||
|
||||
// We perform the additions using the unsigned type U to avoid signed
|
||||
// integer overflows in the non-atomic portion (atomics have well-defined,
|
||||
// two's complement overflow, even signed ones).
|
||||
T parcel1 = 42;
|
||||
T parcel2 = T(0-parcel1);
|
||||
T newValue1 = T(U(value) + parcel1);
|
||||
T newValue2 = T(U(value) + parcel2);
|
||||
|
||||
const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() + parcel2;
|
||||
const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() + parcel1;
|
||||
|
||||
T newValue1 = T(value);
|
||||
if (!needToPreventOverflow)
|
||||
newValue1 += parcel1;
|
||||
T newValue2 = T(value);
|
||||
if (!needToPreventUnderflow)
|
||||
newValue2 += parcel2;
|
||||
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndAddAcquire(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndAddAcquire(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndAddAcquire(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndAddAcquire(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndAddRelease(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndAddRelease(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndAddRelease(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndAddRelease(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndAddOrdered(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndAddOrdered(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndAddOrdered(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndAddOrdered(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
|
||||
// operator+=
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic += parcel1, newValue1);
|
||||
QCOMPARE(atomic += parcel2, T(value));
|
||||
}
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic += parcel2, newValue2);
|
||||
QCOMPARE(atomic += parcel1, T(value));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QAtomicIntegerXX::fetchAndSub()
|
||||
|
|
@ -512,80 +474,55 @@ void tst_QAtomicIntegerXX::fetchAndSub()
|
|||
QFETCH(LargeInt, value);
|
||||
QAtomicInteger<T> atomic(value);
|
||||
|
||||
// We perform the subtractions using the unsigned type U to avoid signed
|
||||
// integer underrflows in the non-atomic portion (atomics have well-defined,
|
||||
// two's complement underflow, even signed ones).
|
||||
T parcel1 = 42;
|
||||
T parcel2 = T(0-parcel1);
|
||||
T newValue1 = T(U(value) - parcel1);
|
||||
T newValue2 = T(U(value) - parcel2);
|
||||
|
||||
const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() - parcel1;
|
||||
const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() - parcel2;
|
||||
|
||||
T newValue1 = T(value);
|
||||
if (!needToPreventUnderflow)
|
||||
newValue1 -= parcel1;
|
||||
T newValue2 = T(value);
|
||||
if (!needToPreventOverflow)
|
||||
newValue2 -= parcel2;
|
||||
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndSubAcquire(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndSubAcquire(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndSubAcquire(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadRelaxed(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndSubAcquire(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadRelaxed(), T(value));
|
||||
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndSubRelease(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndSubRelease(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndSubRelease(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndSubRelease(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic.fetchAndSubOrdered(parcel1), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue1);
|
||||
QCOMPARE(atomic.fetchAndSubOrdered(parcel2), newValue1);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic.fetchAndSubOrdered(parcel2), T(value));
|
||||
QCOMPARE(atomic.loadAcquire(), newValue2);
|
||||
QCOMPARE(atomic.fetchAndSubOrdered(parcel1), newValue2);
|
||||
}
|
||||
QCOMPARE(atomic.loadAcquire(), T(value));
|
||||
|
||||
// operator-=
|
||||
if (!needToPreventUnderflow) {
|
||||
QCOMPARE(atomic -= parcel1, newValue1);
|
||||
QCOMPARE(atomic -= parcel2, T(value));
|
||||
}
|
||||
if (!needToPreventOverflow) {
|
||||
QCOMPARE(atomic -= parcel2, newValue2);
|
||||
QCOMPARE(atomic -= parcel1, T(value));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QAtomicIntegerXX::fetchAndOr()
|
||||
|
|
|
|||
Loading…
Reference in New Issue