stdlib: Fix stdbit.h with -Wconversion for clang

With clang 14 and also with main the tst-stdbit-Wconversion
issues the warnings:

  ../stdlib/stdbit.h:701:40: error: implicit conversion loses integer
  precision: 'int' to 'uint16_t' (aka 'unsigned short')
  [-Werror,-Wimplicit-int-conversion]
    return __x == 0 ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1);
    ~~~~~~                ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ../stdlib/stdbit.h:707:39: error: implicit conversion loses integer
  precision: 'int' to 'uint8_t' (aka 'unsigned char')
  [-Werror,-Wimplicit-int-conversion]
    return __x == 0 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1);
    ~~~~~~                ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
  ../stdlib/stdbit.h:751:40: error: implicit conversion loses integer
  precision: 'int' to 'uint16_t' (aka 'unsigned short')
  [-Werror,-Wimplicit-int-conversion]
    return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) - 1);
    ~~~~~~                ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ../stdlib/stdbit.h:757:39: error: implicit conversion loses integer
  precision: 'int' to 'uint8_t' (aka 'unsigned char')
  [-Werror,-Wimplicit-int-conversion]
    return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);
    ~~~~~~                ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  tst-stdbit-Wconversion.c:45:31: error: implicit conversion loses integer
  precision: 'unsigned short' to 'uint8_t' (aka 'unsigned char')
  [-Werror,-Wimplicit-int-conversion]
    (void) stdc_trailing_zeros (us);
           ~~~~~~~~~~~~~~~~~~~~~^~~
  ../stdlib/stdbit.h:164:30: note: expanded from macro
  'stdc_trailing_zeros'
     : stdc_trailing_zeros_uc (x))
       ~~~~~~~~~~~~~~~~~~~~~~~~^~
  ../stdlib/stdbit.h:191:52: note: expanded from macro
  'stdc_trailing_zeros_uc'
  # define stdc_trailing_zeros_uc(x) (__ctz8_inline (x))
                                      ~~~~~~~~~~~~~  ^
  tst-stdbit-Wconversion.c:46:31: error: implicit conversion loses integer
  precision: 'unsigned int' to 'uint16_t' (aka 'unsigned short')
  [-Werror,-Wimplicit-int-conversion]
    (void) stdc_trailing_zeros (ui);
           ~~~~~~~~~~~~~~~~~~~~~^~~
  ../stdlib/stdbit.h:163:48: note: expanded from macro
  'stdc_trailing_zeros'
     : sizeof (x) == 2 ? stdc_trailing_zeros_us (x)       \
                         ~~~~~~~~~~~~~~~~~~~~~~~~^~
  ../stdlib/stdbit.h:192:53: note: expanded from macro
  'stdc_trailing_zeros_us'
  # define stdc_trailing_zeros_us(x) (__ctz16_inline (x))
                                      ~~~~~~~~~~~~~~  ^
  tst-stdbit-Wconversion.c:46:31: error: implicit conversion loses integer
  precision: 'unsigned int' to 'uint8_t' (aka 'unsigned char')
  [-Werror,-Wimplicit-int-conversion]
    (void) stdc_trailing_zeros (ui);
           ~~~~~~~~~~~~~~~~~~~~~^~~
  ../stdlib/stdbit.h:164:30: note: expanded from macro
  'stdc_trailing_zeros'
     : stdc_trailing_zeros_uc (x))
       ~~~~~~~~~~~~~~~~~~~~~~~~^~
  ../stdlib/stdbit.h:191:52: note: expanded from macro
  'stdc_trailing_zeros_uc'
  # define stdc_trailing_zeros_uc(x) (__ctz8_inline (x))
                                      ~~~~~~~~~~~~~  ^
  tst-stdbit-Wconversion.c:47:31: error: implicit conversion loses integer
  precision: 'unsigned long' to 'uint16_t' (aka 'unsigned short')
  [-Werror,-Wimplicit-int-conversion]
    (void) stdc_trailing_zeros (ul);
           ~~~~~~~~~~~~~~~~~~~~~^~~
  ../stdlib/stdbit.h:163:48: note: expanded from macro
  'stdc_trailing_zeros'
     : sizeof (x) == 2 ? stdc_trailing_zeros_us (x)       \
                         ~~~~~~~~~~~~~~~~~~~~~~~~^~
  ../stdlib/stdbit.h:192:53: note: expanded from macro
  'stdc_trailing_zeros_us'
  # define stdc_trailing_zeros_us(x) (__ctz16_inline (x))
                                      ~~~~~~~~~~~~~~  ^
  [...]

It seems to boiler down to __builtin_clz not having a variant for 8 or
16 bits.  Fix it by explicit casting to the expected types.  Although
not strickly required for older gcc, using the same __pacify macro
simpify the required code.

Checked on x86_64-linux-gnu and i686-linux-gnu.
This commit is contained in:
Adhemerval Zanella 2024-01-04 14:59:28 -03:00
parent c8e31fbf04
commit 48ef5aeb1b

View File

@ -42,7 +42,8 @@
__BEGIN_DECLS
/* Use __pacify_uint16 (N) instead of (uint16_t) (N) when the cast is helpful
only to pacify older GCC (e.g., GCC 10 -Wconversion) or non-GCC. */
only to pacify older GCC (e.g., GCC 10 -Wconversion) or non-GCC (e.g
clang -Wimplicit-int-conversion). */
#if __GNUC_PREREQ (11, 0)
# define __pacify_uint8(n) (n)
# define __pacify_uint16(n) (n)
@ -170,8 +171,8 @@ extern unsigned int stdc_trailing_zeros_ull (unsigned long long int __x)
#define stdc_trailing_zeros(x) \
(sizeof (x) == 8 ? stdc_trailing_zeros_ull (x) \
: sizeof (x) == 4 ? stdc_trailing_zeros_ui (x) \
: sizeof (x) == 2 ? stdc_trailing_zeros_us (x) \
: stdc_trailing_zeros_uc (x))
: sizeof (x) == 2 ? stdc_trailing_zeros_us (__pacify_uint16 (x)) \
: stdc_trailing_zeros_uc (__pacify_uint8 (x)))
#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
static __always_inline unsigned int
@ -274,8 +275,8 @@ extern unsigned int stdc_first_leading_zero_ull (unsigned long long int __x)
#define stdc_first_leading_zero(x) \
(sizeof (x) == 8 ? stdc_first_leading_zero_ull (x) \
: sizeof (x) == 4 ? stdc_first_leading_zero_ui (x) \
: sizeof (x) == 2 ? stdc_first_leading_zero_us (x) \
: stdc_first_leading_zero_uc (x))
: sizeof (x) == 2 ? stdc_first_leading_zero_us (__pacify_uint16 (x)) \
: stdc_first_leading_zero_uc (__pacify_uint8 (x)))
#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
static __always_inline unsigned int
@ -328,8 +329,8 @@ extern unsigned int stdc_first_leading_one_ull (unsigned long long int __x)
#define stdc_first_leading_one(x) \
(sizeof (x) == 8 ? stdc_first_leading_one_ull (x) \
: sizeof (x) == 4 ? stdc_first_leading_one_ui (x) \
: sizeof (x) == 2 ? stdc_first_leading_one_us (x) \
: stdc_first_leading_one_uc (x))
: sizeof (x) == 2 ? stdc_first_leading_one_us (__pacify_uint16 (x)) \
: stdc_first_leading_one_uc (__pacify_uint8 (x)))
#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
static __always_inline unsigned int
@ -382,8 +383,8 @@ extern unsigned int stdc_first_trailing_zero_ull (unsigned long long int __x)
#define stdc_first_trailing_zero(x) \
(sizeof (x) == 8 ? stdc_first_trailing_zero_ull (x) \
: sizeof (x) == 4 ? stdc_first_trailing_zero_ui (x) \
: sizeof (x) == 2 ? stdc_first_trailing_zero_us (x) \
: stdc_first_trailing_zero_uc (x))
: sizeof (x) == 2 ? stdc_first_trailing_zero_us (__pacify_uint16 (x)) \
: stdc_first_trailing_zero_uc (__pacify_uint8 (x)))
#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
static __always_inline unsigned int
@ -436,8 +437,8 @@ extern unsigned int stdc_first_trailing_one_ull (unsigned long long int __x)
#define stdc_first_trailing_one(x) \
(sizeof (x) == 8 ? stdc_first_trailing_one_ull (x) \
: sizeof (x) == 4 ? stdc_first_trailing_one_ui (x) \
: sizeof (x) == 2 ? stdc_first_trailing_one_us (x) \
: stdc_first_trailing_one_uc (x))
: sizeof (x) == 2 ? stdc_first_trailing_one_us (__pacify_uint16 (x)) \
: stdc_first_trailing_one_uc (__pacify_uint8 (x)))
#if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
static __always_inline unsigned int