From 6be8efb8535058beb276fa901e31587c25864e46 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 30 Sep 2022 00:26:11 -0700 Subject: [PATCH] qnumeric_p.h: fix comparison of signed to unsigned in saturation qnumeric_p.h:343:18: error: comparison of integers of different signs: 'int' and 'const unsigned int' [-Werror,-Wsign-compare] note: in instantiation of function template specialization 'qt_saturate' requested here Pick-to: 6.4 6.3 6.2 Task-number: QTBUG-104972 Task-number: COIN-928 Change-Id: I810d70e579eb4e2c8e45fffd171992a457a139dc Reviewed-by: Marc Mutz Reviewed-by: Fabian Kosmale Reviewed-by: Alex Blasche Reviewed-by: Edward Welbourne --- src/corelib/global/qnumeric.cpp | 31 +++++++++++++++++++++++++++++++ src/corelib/global/qnumeric_p.h | 9 +++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp index 16b2b7ca408..e492e3f02a0 100644 --- a/src/corelib/global/qnumeric.cpp +++ b/src/corelib/global/qnumeric.cpp @@ -458,4 +458,35 @@ Q_CORE_EXPORT quint64 qFloatDistance(double a, double b) Returns true if the absolute value of \a f is within 0.00001f of 0.0. */ +template static constexpr T max = std::numeric_limits::max(); +template static constexpr T min = std::numeric_limits::min(); + +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == qint64(max)); + +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == unsigned(max)); +static_assert(qt_saturate(max) == qint64(max)); + +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == quint64(max)); + +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == max); +static_assert(qt_saturate(max) == max); + +static_assert(qt_saturate(min) == min); +static_assert(qt_saturate(min) == qint64(min)); +static_assert(qt_saturate(min) == 0); +static_assert(qt_saturate(min) == 0); + +static_assert(qt_saturate(min) == min); +static_assert(qt_saturate(min) == min); +static_assert(qt_saturate(min) == 0); +static_assert(qt_saturate(min) == 0); + QT_END_NAMESPACE diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 8e08615ab37..f5beb4d38de 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -322,7 +322,7 @@ template bool mul_overflow(T v1, T *r) returns H. Otherwise, returns \c{To(x)}. */ template -static auto qt_saturate(From x) +static constexpr auto qt_saturate(From x) { static_assert(std::is_integral_v); static_assert(std::is_integral_v); @@ -332,6 +332,7 @@ static auto qt_saturate(From x) constexpr auto Hi = (std::numeric_limits::max)(); if constexpr (std::is_signed_v == std::is_signed_v) { + // same signedness, we can accept regular integer conversion rules return x < Lo ? Lo : x > Hi ? Hi : /*else*/ To(x); @@ -340,7 +341,11 @@ static auto qt_saturate(From x) if (x < From{0}) return To{0}; } - return x > Hi ? Hi : To(x); + + // from here on, x >= 0 + using FromU = std::make_unsigned_t; + using ToU = std::make_unsigned_t; + return FromU(x) > ToU(Hi) ? Hi : To(x); // assumes Hi >= 0 } }