diff options
Diffstat (limited to 'src/corelib/kernel')
| -rw-r--r-- | src/corelib/kernel/qobject.cpp | 2 | ||||
| -rw-r--r-- | src/corelib/kernel/qsingleshottimer_p.h | 15 | ||||
| -rw-r--r-- | src/corelib/kernel/qtimer.cpp | 8 |
3 files changed, 21 insertions, 4 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 708b10a75ee..e1129c5d251 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1816,6 +1816,8 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData int QObject::startTimer(int interval, Qt::TimerType timerType) { + // no overflow can happen here: + // 2^31 ms * 1,000,000 always fits a 64-bit signed integer type return startTimer(std::chrono::milliseconds{interval}, timerType); } diff --git a/src/corelib/kernel/qsingleshottimer_p.h b/src/corelib/kernel/qsingleshottimer_p.h index d7e33c52212..dd1402f63a1 100644 --- a/src/corelib/kernel/qsingleshottimer_p.h +++ b/src/corelib/kernel/qsingleshottimer_p.h @@ -19,6 +19,7 @@ #include "qabstracteventdispatcher.h" #include "qcoreapplication.h" #include "qmetaobject_p.h" +#include "private/qnumeric_p.h" #include <chrono> @@ -43,6 +44,20 @@ public: inline void startTimerForReceiver(Duration interval, Qt::TimerType timerType, const QObject *receiver); + static Duration fromMsecs(std::chrono::milliseconds ms) + { + using namespace std::chrono; + using ratio = std::ratio_divide<std::milli, Duration::period>; + static_assert(ratio::den == 1); + + Duration::rep r; + if (qMulOverflow<ratio::num>(ms.count(), &r)) { + qWarning("QTimer::singleShot(std::chrono::milliseconds, ...): " + "interval argument overflowed when converted to nanoseconds."); + return Duration::max(); + } + return Duration{r}; + } Q_SIGNALS: void timeout(); diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index cc46c1433b5..294369c1b33 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -213,7 +213,7 @@ void QTimer::start() if (d->isActive()) // stop running timer stop(); - const auto newId = Qt::TimerId{QObject::startTimer(d->inter * 1ms, d->type)}; + Qt::TimerId newId{ QObject::startTimer(d->inter * 1ms, d->type) }; // overflow impossible if (newId > Qt::TimerId::Invalid) { d->id = newId; d->isActiveData.notify(); @@ -332,7 +332,7 @@ void QTimer::singleShotImpl(std::chrono::milliseconds msec, Qt::TimerType timerT return; } - new QSingleShotTimer(msec, timerType, receiver, slotObj); + new QSingleShotTimer(QSingleShotTimer::fromMsecs(msec), timerType, receiver, slotObj); } /*! @@ -396,7 +396,7 @@ void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, Qt::QueuedConnection); return; } - (void) new QSingleShotTimer(msec, timerType, receiver, member); + (void) new QSingleShotTimer(QSingleShotTimer::fromMsecs(msec), timerType, receiver, member); } } @@ -592,7 +592,7 @@ void QTimer::setInterval(std::chrono::milliseconds interval) d->inter.setValueBypassingBindings(msec); if (d->isActive()) { // create new timer QObject::killTimer(d->id); // restart timer - const auto newId = Qt::TimerId{QObject::startTimer(msec * 1ms, d->type)}; + Qt::TimerId newId{ QObject::startTimer(msec * 1ms, d->type) }; // overflow impossible if (newId > Qt::TimerId::Invalid) { // Restarted successfully. No need to update the active state. d->id = newId; |
