Avoid UB (and the consequent need to suppress an MSVC warning)

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 <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
bb10
Edward Welbourne 2021-08-24 14:56:53 +02:00
parent 0564e4afba
commit 6db5fd5918
2 changed files with 7 additions and 14 deletions

View File

@ -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<qlonglong>::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);
}

View File

@ -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<qlonglong>::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);
}
/*!