From 9a66a9ac4a6c0881121f169799bda227e945ff8c Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Fri, 23 Dec 2022 22:44:34 -0700 Subject: [PATCH] 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. --- .../Libraries/LibWasm/AbstractMachine/Operators.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Operators.h b/Userland/Libraries/LibWasm/AbstractMachine/Operators.h index 5d3305a0cf..a3a61589d1 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Operators.h +++ b/Userland/Libraries/LibWasm/AbstractMachine/Operators.h @@ -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 = [](ConvertT truncated_value) { if (truncated_value < NumericLimits::min()) return NumericLimits::min(); - if (static_cast(truncated_value) > static_cast(NumericLimits::max())) - return NumericLimits::max(); + if constexpr (IsSame) { + if (truncated_value >= static_cast(NumericLimits::max())) + return NumericLimits::max(); + } else { + if (static_cast(truncated_value) >= static_cast(NumericLimits::max())) + return NumericLimits::max(); + } return static_cast(truncated_value); };