summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWasm
diff options
context:
space:
mode:
authorAndrew Kaster <akaster@serenityos.org>2022-12-23 22:44:34 -0700
committerAndrew Kaster <andrewdkaster@gmail.com>2022-12-25 07:58:58 -0700
commit9a66a9ac4a6c0881121f169799bda227e945ff8c (patch)
treee52bcd7ed6eae70f3bbd812a809fe453fb4e0dbd /Userland/Libraries/LibWasm
parent8d015bd71c23ea4cbc964139569797d687b1230c (diff)
downloadserenity-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.h11
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);
};