[libc-commits] [libc] 80079c9 - [libc] Fix new warning in DyadicFloat::as_mantissa_type_rounded (#131148)

via libc-commits libc-commits at lists.llvm.org
Fri Mar 14 04:57:28 PDT 2025


Author: Simon Tatham
Date: 2025-03-14T11:57:25Z
New Revision: 80079c9c2f55ddfc5b1d5235d5ed6a2981fa6a97

URL: https://github.com/llvm/llvm-project/commit/80079c9c2f55ddfc5b1d5235d5ed6a2981fa6a97
DIFF: https://github.com/llvm/llvm-project/commit/80079c9c2f55ddfc5b1d5235d5ed6a2981fa6a97.diff

LOG: [libc] Fix new warning in DyadicFloat::as_mantissa_type_rounded (#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!)

Added: 
    

Modified: 
    libc/src/__support/FPUtil/dyadic_float.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 16b690be08612..5ef35de296529 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -455,7 +455,11 @@ template <size_t Bits> struct DyadicFloat {
       if (exponent > 0) {
         new_mant <<= exponent;
       } else if (exponent < 0) {
-        size_t shift = -exponent;
+        // Cast the exponent to size_t before negating it, rather than after,
+        // to avoid undefined behavior negating INT_MIN as an integer (although
+        // exponents coming in to this function _shouldn't_ be that large). The
+        // result should always end up as a positive size_t.
+        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