summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global/qnumeric
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-10-29 12:39:58 +0100
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-11-20 11:08:05 +0000
commit5ff7a3d96e0ce0dcb3d388b53d038cdd40c7a975 (patch)
tree0a188d045a0aa86e0f94c80f6ef43ec964592c7b /tests/auto/corelib/global/qnumeric
parent986a5262e3e753958a6ec9058eb7332d44a9065f (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.cpp31
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"