diff options
author | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2015-10-29 12:39:58 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2015-11-20 11:08:05 +0000 |
commit | 5ff7a3d96e0ce0dcb3d388b53d038cdd40c7a975 (patch) | |
tree | 0a188d045a0aa86e0f94c80f6ef43ec964592c7b /tests/auto/corelib/global/qnumeric | |
parent | 986a5262e3e753958a6ec9058eb7332d44a9065f (diff) |
Add {add,sub,mul}_overflow for signed integers.
In C++, signed overflow math is Undefined Behavior. However, many CPUs
do implement some way to check for overflow. Some compilers expose
intrinsics to use this functionality. If the no intrinsic is exposed,
overflow checking can be done by widening the result type and "manually"
checking for overflow. Or, for X86, by using inline assembly to use the
CPU features.
Used in QtQml.
Change-Id: I2ef2523ccaa98f6757a45e24862a2fa730a26bb0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/global/qnumeric')
-rw-r--r-- | tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp index 01ff3a6c7e..1847056de5 100644 --- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp +++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp @@ -55,6 +55,7 @@ private slots: void addOverflow(); void mulOverflow_data(); void mulOverflow(); + void signedOverflow(); }; void tst_QNumeric::fuzzyCompare_data() @@ -378,5 +379,35 @@ void tst_QNumeric::mulOverflow() MulOverflowDispatch<quint64>()(); } +void tst_QNumeric::signedOverflow() +{ + const int minInt = std::numeric_limits<int>::min(); + const int maxInt = std::numeric_limits<int>::max(); + int r; + + QCOMPARE(add_overflow(minInt + 1, int(-1), &r), false); + QCOMPARE(add_overflow(minInt, int(-1), &r), true); + QCOMPARE(add_overflow(minInt, minInt, &r), true); + QCOMPARE(add_overflow(maxInt - 1, int(1), &r), false); + QCOMPARE(add_overflow(maxInt, int(1), &r), true); + QCOMPARE(add_overflow(maxInt, maxInt, &r), true); + + QCOMPARE(sub_overflow(minInt + 1, int(1), &r), false); + QCOMPARE(sub_overflow(minInt, int(1), &r), true); + QCOMPARE(sub_overflow(minInt, maxInt, &r), true); + QCOMPARE(sub_overflow(maxInt - 1, int(-1), &r), false); + QCOMPARE(sub_overflow(maxInt, int(-1), &r), true); + QCOMPARE(sub_overflow(maxInt, minInt, &r), true); + + QCOMPARE(mul_overflow(minInt, int(1), &r), false); + QCOMPARE(mul_overflow(minInt, int(-1), &r), true); + QCOMPARE(mul_overflow(minInt, int(2), &r), true); + QCOMPARE(mul_overflow(minInt, minInt, &r), true); + QCOMPARE(mul_overflow(maxInt, int(1), &r), false); + QCOMPARE(mul_overflow(maxInt, int(-1), &r), false); + QCOMPARE(mul_overflow(maxInt, int(2), &r), true); + QCOMPARE(mul_overflow(maxInt, maxInt, &r), true); +} + QTEST_APPLESS_MAIN(tst_QNumeric) #include "tst_qnumeric.moc" |