1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:27:35 +00:00

LibWasm: Split SaturatingTruncate conversion function by float/non-float

It's possible to construct a floating point value that when converted to
double is not larger than i64::max(), but when remaining a float is
larger. This patch avoids that edge case with some even less exciting if
constexpr branches to fix a float-cast-overflow UBSAN error on macOS
with llvm 15.0.6.
This commit is contained in:
Andrew Kaster 2022-12-23 22:44:34 -07:00 committed by Andrew Kaster
parent 8d015bd71c
commit 9a66a9ac4a

View file

@ -431,11 +431,16 @@ struct SaturatingTruncate {
// FIXME: This assumes that all values in ResultT are representable in 'double'.
// that assumption is not correct, which makes this function yield incorrect values
// for 'edge' values of type i64.
constexpr auto convert = [](auto truncated_value) {
constexpr auto convert = []<typename ConvertT>(ConvertT truncated_value) {
if (truncated_value < NumericLimits<ResultT>::min())
return NumericLimits<ResultT>::min();
if (static_cast<double>(truncated_value) > static_cast<double>(NumericLimits<ResultT>::max()))
return NumericLimits<ResultT>::max();
if constexpr (IsSame<ConvertT, float>) {
if (truncated_value >= static_cast<ConvertT>(NumericLimits<ResultT>::max()))
return NumericLimits<ResultT>::max();
} else {
if (static_cast<double>(truncated_value) >= static_cast<double>(NumericLimits<ResultT>::max()))
return NumericLimits<ResultT>::max();
}
return static_cast<ResultT>(truncated_value);
};