libc/stdbit/stdc_bit_ceil.c doesn't compile on msp430-elf

Message ID CAH6eHdS+hMXufNCtDqBBfe1NuQ8hM=rx1NB1s8QegGidN1XE0A@mail.gmail.com
State New
Headers
Series libc/stdbit/stdc_bit_ceil.c doesn't compile on msp430-elf |

Commit Message

Jonathan Wakely April 20, 2026, 2:27 p.m. UTC
  make[3]: Entering directory
'/home/jwakely/src/gcc/build-msp430/gcc-obj/msp430-elf/newlib'
 CC       libc/stdbit/libc_a-stdc_bit_ceil.o
/home/jwakely/src/gcc/gcc/newlib/libc/stdbit/stdc_bit_ceil.c:27:1:
error: static assertion failed: "stdc_bit_ceil_us needs USHRT_WIDTH <
UINT_WIDTH"
  27 | _Static_assert(USHRT_WIDTH < UINT_WIDTH,
     | ^~~~~~~~~~~~~~

This fails because both values are 16. Would this be a better implementation?
  

Comments

Jonathan Wakely April 20, 2026, 2:59 p.m. UTC | #1
stdc_leading_ones.c fails similarly

 CC       libc/stdbit/libc_a-stdc_leading_ones.o
/home/jwakely/src/gcc/gcc/newlib/libc/stdbit/stdc_leading_ones.c:26:1:
error: static assertion failed: "stdc_leading_ones_us needs
USHRT_WIDTH < UINT_WIDTH"
  26 | _Static_assert(USHRT_WIDTH < UINT_WIDTH,
     | ^~~~~~~~~~~~~~


Which could be fixed by:

--- a/newlib/libc/stdbit/stdc_leading_ones.c
+++ b/newlib/libc/stdbit/stdc_leading_ones.c
@@ -22,13 +22,15 @@ stdc_leading_ones_uc(unsigned char x)
       return (__builtin_clz(~(x << offset)));
}

-/* Avoid triggering undefined behavior if x == 0. */
-_Static_assert(USHRT_WIDTH < UINT_WIDTH,
-    "stdc_leading_ones_us needs USHRT_WIDTH < UINT_WIDTH");
-
unsigned int
stdc_leading_ones_us(unsigned short x)
{
+#if USHRT_WIDTH == UINT_WIDTH
+       /* Avoid triggering undefined behavior if x == 0. */
+       if (x == ~0U)
+               return (USHRT_WIDTH);
+#endif
+
       const int offset = UINT_WIDTH - USHRT_WIDTH;

       return (__builtin_clz(~(x << offset)));

The comment is wrong though, isn't it? And the one on line 13. The UB
happens when x == ~0 not when x == 0.
  

Patch

--- a/newlib/libc/stdbit/stdc_bit_ceil.c
+++ b/newlib/libc/stdbit/stdc_bit_ceil.c
@@ -23,16 +23,17 @@  stdc_bit_ceil_uc(unsigned char x)
       return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
}

-/* Ensure we don't shift 1U out of range. */
-_Static_assert(USHRT_WIDTH < UINT_WIDTH,
-    "stdc_bit_ceil_us needs USHRT_WIDTH < UINT_WIDTH");
-
unsigned short
stdc_bit_ceil_us(unsigned short x)
{
       if (x <= 1)
               return (1);

+#if USHRT_WIDTH == UINT_WIDTH
+       if (x > USHRT_MAX/2 + 1)
+               return (0);
+#endif
+
       return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
}