From 6197078fbd74461e3ef5f6725f34fa4d1b0939f4 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 23 May 2024 19:58:19 +0200 Subject: [PATCH] QDateTime::fromStdTimePoint: fix the constraint The constraint requires the input time_point's duration to be convertible to milliseconds. That's inaccurate: we need to check the duration of the time_point we get from the clock_cast, not the input. In general, clock_cast is allowed to return arbitrary durations, so it may not match the input. (It indeed doesn't match for some standard clocks, like gps_clock.) Task-number: QTBUG-125587 Change-Id: I5a93317c8cdc0a3cef4acab17c656e2e5dac5d8d Reviewed-by: Thiago Macieira (cherry picked from commit e95812df85d98689d51bed92acce51e0e250f854) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/time/qdatetime.cpp | 13 +++++++++++-- src/corelib/time/qdatetime.h | 19 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 3dc5c1f71a1..235222043dc 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -5352,8 +5352,17 @@ QDateTime QDateTime::currentDateTimeUtc() Constructs a datetime representing the same point in time as \a time, using Qt::UTC as its specification. - The clock of \a time must be compatible with \c{std::chrono::system_clock}, - and the duration type must be convertible to \c{std::chrono::milliseconds}. + The clock of \a time must be compatible with + \c{std::chrono::system_clock}; in particular, a conversion + supported by \c{std::chrono::clock_cast} must exist. After the + conversion, the duration type of the result must be convertible to + \c{std::chrono::milliseconds}. + + If this is not the case, the caller must perform the necessary + clock conversion towards \c{std::chrono::system_clock} and the + necessary conversion of the duration type + (cast/round/floor/ceil/...) so that the input to this function + satisfies the constraints above. \note This function requires C++20. diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h index 56601e5d783..29da29a5d0e 100644 --- a/src/corelib/time/qdatetime.h +++ b/src/corelib/time/qdatetime.h @@ -510,6 +510,17 @@ public: #if __cpp_lib_chrono >= 201907L || defined(Q_QDOC) #if __cpp_concepts >= 201907L || defined(Q_QDOC) +private: + // The duration type of the result of a clock_cast. + // This duration may differ from the duration of the input. + template + using system_clock_cast_duration = decltype( + std::chrono::clock_cast( + std::declval &>() + ).time_since_epoch() + ); + +public: // Generic clock, as long as it's compatible with us (= system_clock) template static QDateTime fromStdTimePoint(const std::chrono::time_point &time) @@ -517,8 +528,12 @@ public: requires(const std::chrono::time_point &t) { // the clock can be converted to system_clock std::chrono::clock_cast(t); - // the duration can be converted to milliseconds - requires std::is_convertible_v; + // after the conversion to system_clock, the duration type + // we get is convertible to milliseconds + requires std::is_convertible_v< + system_clock_cast_duration, + std::chrono::milliseconds + >; } { const auto sysTime = std::chrono::clock_cast(time);