@@ -259,7 +259,7 @@ struct Floor {
259
259
};
260
260
struct Truncate {
261
261
template <typename Lhs>
262
- auto operator ()(Lhs lhs) const
262
+ Result<Lhs, StringView> operator ()(Lhs lhs) const
263
263
{
264
264
if constexpr (IsSame<Lhs, float >)
265
265
return truncf (lhs);
@@ -327,10 +327,13 @@ struct CheckedTruncate {
327
327
else
328
328
VERIFY_NOT_REACHED ();
329
329
330
- if (NumericLimits<ResultT>::min () <= truncated && static_cast <double >(NumericLimits<ResultT>::max ()) >= static_cast <double >(truncated))
331
- return static_cast <ResultT>(truncated);
330
+ // FIXME: This function assumes that all values of ResultT are representable in Lhs
331
+ // the assumption comes from the fact that this was used exclusively by LibJS,
332
+ // which only considers values that are all representable in 'double'.
333
+ if (!AK::is_within_range<ResultT>(truncated))
334
+ return " Truncation out of range" sv;
332
335
333
- return " Truncation out of range " sv ;
336
+ return static_cast <ResultT>(truncated) ;
334
337
}
335
338
336
339
static StringView name () { return " truncate.checked" ; }
@@ -424,6 +427,9 @@ struct SaturatingTruncate {
424
427
return NumericLimits<ResultT>::max ();
425
428
}
426
429
430
+ // FIXME: This assumes that all values in ResultT are representable in 'double'.
431
+ // that assumption is not correct, which makes this function yield incorrect values
432
+ // for 'edge' values of type i64.
427
433
constexpr auto convert = [](auto truncated_value) {
428
434
if (truncated_value < NumericLimits<ResultT>::min ())
429
435
return NumericLimits<ResultT>::min ();
0 commit comments