[libc-commits] [libc] [libc] Fix new warning in DyadicFloat::as_mantissa_type_rounded (PR #131148)
Simon Tatham via libc-commits
libc-commits at lists.llvm.org
Thu Mar 13 07:32:58 PDT 2025
https://github.com/statham-arm created https://github.com/llvm/llvm-project/pull/131148
The affected line of code converts a float's exponent from `int` to `size_t`, negating it in the process. Following clang commit 773e88f9d61399c, this provokes a warning, presumably because the conversion goes wrong if `size_t` is wider than `int` and the input value is `INT_MIN`: negating it within the `int` type is undefined behavior, with the likely (though not guaranteed) effect of leaving it still at `INT_MIN` and then sign-extending that on promotion to `size_t`.
This fix adds a cast so that the promotion to `size_t` happens _before_ the negation, so that the negative input value will _always_ be sign-extended, and then the negation will make it positive again.
(I don't believe this case will actually come up. `DyadicFloat` is a helper system used in processing ordinary float formats, so nothing is expected to generate an exponent with even a 16-bit absolute value, let alone 31. But it's as easy to fix it to be robust as it is to just suppress the warning!)
>From 6703fefe3bb9c8a0f6ace46cc5f0df91f869fda4 Mon Sep 17 00:00:00 2001
From: Simon Tatham <simon.tatham at arm.com>
Date: Tue, 11 Mar 2025 16:12:26 +0000
Subject: [PATCH] [libc] Fix new warning in
DyadicFloat::as_mantissa_type_rounded
The affected line of code converts a float's exponent from `int` to
`size_t`, negating it in the process. Following clang commit
773e88f9d61399c, this provokes a warning, presumably because the
conversion goes wrong if `size_t` is wider than `int` and the input
value is `INT_MIN`: negating it within the `int` type is undefined
behavior, with the likely (though not guaranteed) effect of leaving it
still at `INT_MIN` and then sign-extending that on promotion to
`size_t`.
This fix adds a cast so that the promotion to `size_t` happens
_before_ the negation, so that the negative input value will _always_
be sign-extended, and then the negation will make it positive again.
(I don't believe this case will actually come up. `DyadicFloat` is a
helper system used in processing ordinary float formats, so nothing is
expected to generate an exponent with even a 16-bit absolute value,
let alone 31. But it's as easy to fix it to be robust as it is to just
suppress the warning!)
---
libc/src/__support/FPUtil/dyadic_float.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 16b690be08612..048db66aff984 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -455,7 +455,7 @@ template <size_t Bits> struct DyadicFloat {
if (exponent > 0) {
new_mant <<= exponent;
} else if (exponent < 0) {
- size_t shift = -exponent;
+ size_t shift = -static_cast<size_t>(exponent);
new_mant >>= shift;
round_dir = rounding_direction(mantissa, shift, sign);
if (round_dir > 0)
More information about the libc-commits
mailing list