From 6db5fd5918e9c2fb73d61de13356307248c4f2e9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 24 Aug 2021 14:56:53 +0200 Subject: [PATCH] Avoid UB (and the consequent need to suppress an MSVC warning) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Converting a negative signed value to its absolute value in the matching unsigned type can be done by adding one, negating (which we can now do without the UB), casting and then adding one again. This is cleaner than casting the negative value to the unsigned type in order to then "negate" it within that type, about which MSVC grumbles; we can now avoid the need to suppress that grumble. Change-Id: I9148ead23c928aeb2b90884a2f2e292fdf3af5e3 Reviewed-by: Thiago Macieira Reviewed-by: MÃ¥rten Nordheim --- src/corelib/text/qlocale.cpp | 13 +++++-------- src/corelib/text/qstring.cpp | 8 ++------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 5abc4d3a09..2999793857 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -3642,20 +3642,17 @@ QString QLocaleData::signPrefix(bool negative, unsigned flags) const return {}; } -QString QLocaleData::longLongToString(qlonglong l, int precision, +QString QLocaleData::longLongToString(qlonglong n, int precision, int base, int width, unsigned flags) const { - bool negative = l < 0; + bool negative = n < 0; -QT_WARNING_PUSH - /* "unary minus operator applied to unsigned type, result still unsigned" */ -QT_WARNING_DISABLE_MSVC(4146) /* Negating std::numeric_limits::min() hits undefined behavior, so - taking an absolute value has to cast to unsigned to change sign. + taking an absolute value has to take a slight detour. */ - QString numStr = qulltoa(negative ? -qulonglong(l) : qulonglong(l), base, zeroDigit()); -QT_WARNING_POP + QString numStr = qulltoa(negative ? 1u + qulonglong(-(n + 1)) : qulonglong(n), + base, zeroDigit()); return applyIntegerFormatting(std::move(numStr), negative, precision, base, width, flags); } diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 8dbf996f73..938712a36d 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -7374,16 +7374,12 @@ QString QString::number(qlonglong n, int base) base = 10; } #endif -QT_WARNING_PUSH - /* "unary minus operator applied to unsigned type, result still unsigned" */ -QT_WARNING_DISABLE_MSVC(4146) bool negative = n < 0; /* Negating std::numeric_limits::min() hits undefined behavior, so - taking an absolute value has to cast to unsigned to change sign. + taking an absolute value has to take a slight detour. */ - return qulltoBasicLatin(negative ? -qulonglong(n) : qulonglong(n), base, negative); -QT_WARNING_POP + return qulltoBasicLatin(negative ? 1u + qulonglong(-(n + 1)) : qulonglong(n), base, negative); } /*!