diff options
author | Andrew Kaster <akaster@serenityos.org> | 2022-12-23 22:44:34 -0700 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-12-25 07:58:58 -0700 |
commit | 9a66a9ac4a6c0881121f169799bda227e945ff8c (patch) | |
tree | e52bcd7ed6eae70f3bbd812a809fe453fb4e0dbd /Userland/Libraries/LibWasm | |
parent | 8d015bd71c23ea4cbc964139569797d687b1230c (diff) | |
download | serenity-9a66a9ac4a6c0881121f169799bda227e945ff8c.zip |
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.
Diffstat (limited to 'Userland/Libraries/LibWasm')
-rw-r--r-- | Userland/Libraries/LibWasm/AbstractMachine/Operators.h | 11 |
1 files 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 = []<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); }; |