path: root/tests
diff options
authorMarc Mutz <>2016-10-17 13:00:04 +0200
committerMarc Mutz <>2016-10-18 16:06:28 +0000
commite80faf3db61ca9c701cd86876e3bce8e33226576 (patch)
tree279ad81c075f711ea776f5cff37db88c9571d129 /tests
parent3a1245fdace1b008018dfb6b6334d5ebaec81b5e (diff)
QTimer: don't circumvent <chrono> safety net
By templating on the <chrono> types and unconditionally using duration_cast to coerce the duration into a milliseconds, we violate a principal design rule of <chrono>, namely that non- narrowing conversions are implicit, but narrowing conversions need duration_cast. By accepting any duration, we allow non- sensical code such as QTimer::singleShot(10us, ...) to compile, which is misleading, since it's actually a zero- timeout timer. Overloading a non-template with a template also has adverse effects: it breaks qOverload(). Fix by replacing the function templates with functions that just take std::chrono::milliseconds. This way, benign code such as QTimer::singleShot(10s, ...) QTimer::singleShot(10min, ...) QTimer::singleShot(1h, ...) work as expected, but attempts to use sub-millisecond resolution fails to compile / needs an explicit user- provided duration_cast. To allow future extension to more precise timers, forcibly inline the functions, so they don't partake in the ABI of the class and we can later support sub-millisecond resolution by simply taking micro- or nano- instead of milliseconds. Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de Reviewed-by: Thiago Macieira <>
Diffstat (limited to 'tests')
1 files changed, 13 insertions, 3 deletions
diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
index 28df01cc16..fe97695d19 100644
--- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
+++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
@@ -216,6 +216,16 @@ void tst_QTimer::remainingTimeDuringActivation()
+namespace {
+#if QT_HAS_INCLUDE(<chrono>)
+ template <typename T>
+ std::chrono::milliseconds to_ms(T t)
+ { return std::chrono::duration_cast<std::chrono::milliseconds>(t); }
+} // unnamed namespace
void tst_QTimer::basic_chrono()
#if !QT_HAS_INCLUDE(<chrono>)
@@ -225,7 +235,7 @@ void tst_QTimer::basic_chrono()
using namespace std::chrono;
TimerHelper helper;
QTimer timer;
- timer.setInterval(nanoseconds(0));
+ timer.setInterval(to_ms(nanoseconds(0)));
QCOMPARE(timer.intervalAsDuration().count(), milliseconds::rep(0));
QCOMPARE(timer.remainingTimeAsDuration().count(), milliseconds::rep(0));
@@ -248,7 +258,7 @@ void tst_QTimer::basic_chrono()
QVERIFY(helper.count > oldCount);
helper.count = 0;
- timer.start(microseconds(200000));
+ timer.start(to_ms(microseconds(200000)));
QCOMPARE(timer.intervalAsDuration().count(), milliseconds::rep(200));
QCOMPARE(helper.count, 0);
@@ -864,7 +874,7 @@ void tst_QTimer::singleShot_chrono()
QCOMPARE(nhelper.count, 1);
int count = 0;
- QTimer::singleShot(microseconds(0), CountedStruct(&count));
+ QTimer::singleShot(to_ms(microseconds(0)), CountedStruct(&count));
QCOMPARE(count, 1);