fixing UB overflow in line 274 in wide_integer_impl.h

This commit is contained in:
myrrc 2020-11-10 16:51:23 +03:00
parent e460248624
commit 9d3788f264

View File

@ -232,6 +232,7 @@ struct integer<Bits, Signed>::_impl
constexpr uint64_t max_uint = std::numeric_limits<uint64_t>::max(); constexpr uint64_t max_uint = std::numeric_limits<uint64_t>::max();
constexpr int64_t max_int = std::numeric_limits<int64_t>::max(); constexpr int64_t max_int = std::numeric_limits<int64_t>::max();
constexpr size_t max_sizet = std::numeric_limits<size_t>::max(); constexpr size_t max_sizet = std::numeric_limits<size_t>::max();
constexpr long double max_int_long_double = static_cast<long double>(max_int);
if ((rhs > 0 && rhs < max_uint) || if ((rhs > 0 && rhs < max_uint) ||
(rhs < 0 && rhs > std::numeric_limits<int64_t>::min())) (rhs < 0 && rhs > std::numeric_limits<int64_t>::min()))
@ -268,13 +269,18 @@ struct integer<Bits, Signed>::_impl
"On your system long double has less than 64 precision bits," "On your system long double has less than 64 precision bits,"
"which may result in UB when initializing double from int64_t"); "which may result in UB when initializing double from int64_t");
if (r - to_diff > static_cast<long double>(max_int)) if (long double diff = r - to_diff; diff > max_int_long_double)
{ {
self += max_int; uint64_t diff_multiplier = max_uint;
self += static_cast<int64_t>(r - to_diff - max_int);
if (const long double multiplier = diff / max_int_long_double; multiplier < max_uint)
diff_multiplier = multiplier;
self += max_int_long_double * diff_multiplier;
self += static_cast<int64_t>(diff - max_int_long_double * diff_multiplier);
} }
else else
self += to_Integral(r - to_diff); self += static_cast<int64_t>(diff);
if (rhs < 0) if (rhs < 0)
self = -self; self = -self;