public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion
@ 2024-01-05 17:17 Adhemerval Zanella
  2024-01-05 17:17 ` [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc Adhemerval Zanella
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2024-01-05 17:17 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joseph Myers

The tst-stdbit-Wconversion test triggers some warnings with older
gcc and also with clang.  Although these warnings might be considered
false alarms, it would be good to avoid them on a standard header if
possible.

Adhemerval Zanella (2):
  stdlib: Fix stdbit.h with -Wconversion for older gcc
  stdlib: Fix stdbit.h with -Wconversion for clang

 stdlib/stdbit.h | 55 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 18 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc
  2024-01-05 17:17 [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion Adhemerval Zanella
@ 2024-01-05 17:17 ` Adhemerval Zanella
  2024-01-05 17:17 ` [PATCH 2/2] stdlib: Fix stdbit.h with -Wconversion for clang Adhemerval Zanella
  2024-01-05 17:31 ` [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion Joseph Myers
  2 siblings, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2024-01-05 17:17 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joseph Myers

With gcc 6.5.0, 7.5.0, 8.5.0, and 9.5.0 the tst-stdbit-Wconversion
issues the warnings:

../stdlib/stdbit.h: In function ‘__clo16_inline’:
../stdlib/stdbit.h:128:26: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __clz16_inline (~__x);
                          ^
../stdlib/stdbit.h: In function ‘__clo8_inline’:
../stdlib/stdbit.h:134:25: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __clz8_inline (~__x);
                         ^
../stdlib/stdbit.h: In function ‘__cto16_inline’:
../stdlib/stdbit.h:232:26: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __ctz16_inline (~__x);
                          ^
../stdlib/stdbit.h: In function ‘__cto8_inline’:
../stdlib/stdbit.h:238:25: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __ctz8_inline (~__x);
                         ^
../stdlib/stdbit.h: In function ‘__bf16_inline’:
../stdlib/stdbit.h:701:23: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x == 0 ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1);
          ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../stdlib/stdbit.h: In function ‘__bf8_inline’:
../stdlib/stdbit.h:707:23: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x == 0 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1);
          ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../stdlib/stdbit.h: In function ‘__bc16_inline’:
../stdlib/stdbit.h:751:59: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) -
1);
                                                           ^~~
../stdlib/stdbit.h:751:23: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) -
1);
          ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../stdlib/stdbit.h: In function ‘__bc8_inline’:
../stdlib/stdbit.h:757:57: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);
                                                         ^~~
../stdlib/stdbit.h:757:23: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);

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.

Checked on x86_64-linux-gnu and i686-linux-gnu with gcc 9.5.0.
---
 stdlib/stdbit.h | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/stdlib/stdbit.h b/stdlib/stdbit.h
index 773b2ab72d..61165dd725 100644
--- a/stdlib/stdbit.h
+++ b/stdlib/stdbit.h
@@ -41,6 +41,16 @@
 
 __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.  */
+#if __GNUC_PREREQ (11, 0)
+# define __pacify_uint8(n)  (n)
+# define __pacify_uint16(n) (n)
+#else
+# define __pacify_uint8(n)  ((uint8_t) (n))
+# define __pacify_uint16(n) ((uint16_t) (n))
+#endif
+
 /* Count leading zeros.  */
 extern unsigned int stdc_leading_zeros_uc (unsigned char __x)
      __THROW __attribute_const__;
@@ -125,13 +135,13 @@ __clo32_inline (uint32_t __x)
 static __always_inline unsigned int
 __clo16_inline (uint16_t __x)
 {
-  return __clz16_inline (~__x);
+  return __clz16_inline (__pacify_uint16 (~__x));
 }
 
 static __always_inline unsigned int
 __clo8_inline (uint8_t __x)
 {
-  return __clz8_inline (~__x);
+  return __clz8_inline (__pacify_uint8 (~__x));
 }
 
 # define stdc_leading_ones_uc(x) (__clo8_inline (x))
@@ -229,13 +239,13 @@ __cto32_inline (uint32_t __x)
 static __always_inline unsigned int
 __cto16_inline (uint16_t __x)
 {
-  return __ctz16_inline (~__x);
+  return __ctz16_inline (__pacify_uint16 (~__x));
 }
 
 static __always_inline unsigned int
 __cto8_inline (uint8_t __x)
 {
-  return __ctz8_inline (~__x);
+  return __ctz8_inline (__pacify_uint8 (~__x));
 }
 
 # define stdc_trailing_ones_uc(x) (__cto8_inline (x))
@@ -698,13 +708,15 @@ __bf32_inline (uint32_t __x)
 static __always_inline uint16_t
 __bf16_inline (uint16_t __x)
 {
-  return __x == 0 ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1);
+  return __pacify_uint16 (__x == 0
+			  ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1));
 }
 
 static __always_inline uint8_t
 __bf8_inline (uint8_t __x)
 {
-  return __x == 0 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1);
+  return __pacify_uint8 (__x == 0
+			 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1));
 }
 
 # define stdc_bit_floor_uc(x) ((unsigned char) __bf8_inline (x))
@@ -748,13 +760,19 @@ __bc32_inline (uint32_t __x)
 static __always_inline uint16_t
 __bc16_inline (uint16_t __x)
 {
-  return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) - 1);
+  return __pacify_uint16 (__x <= 1
+			  ? 1
+			  : ((uint16_t) 2)
+			    << (__bw16_inline ((uint16_t) (__x - 1)) - 1));
 }
 
 static __always_inline uint8_t
 __bc8_inline (uint8_t __x)
 {
-  return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);
+  return __pacify_uint8 (__x <= 1
+			 ? 1
+			 : ((uint8_t) 2)
+			   << (__bw8_inline ((uint8_t) (__x - 1)) - 1));
 }
 
 # define stdc_bit_ceil_uc(x) ((unsigned char) __bc8_inline (x))
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/2] stdlib: Fix stdbit.h with -Wconversion for clang
  2024-01-05 17:17 [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion Adhemerval Zanella
  2024-01-05 17:17 ` [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc Adhemerval Zanella
@ 2024-01-05 17:17 ` Adhemerval Zanella
  2024-01-05 17:31 ` [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion Joseph Myers
  2 siblings, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2024-01-05 17:17 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joseph Myers

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.
---
 stdlib/stdbit.h | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/stdlib/stdbit.h b/stdlib/stdbit.h
index 61165dd725..f334eb174d 100644
--- a/stdlib/stdbit.h
+++ b/stdlib/stdbit.h
@@ -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
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion
  2024-01-05 17:17 [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion Adhemerval Zanella
  2024-01-05 17:17 ` [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc Adhemerval Zanella
  2024-01-05 17:17 ` [PATCH 2/2] stdlib: Fix stdbit.h with -Wconversion for clang Adhemerval Zanella
@ 2024-01-05 17:31 ` Joseph Myers
  2 siblings, 0 replies; 6+ messages in thread
From: Joseph Myers @ 2024-01-05 17:31 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

These patches are OK.

-- 
Joseph S. Myers
jsm@polyomino.org.uk

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc
  2024-01-04 19:47 ` [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc Adhemerval Zanella
@ 2024-01-04 20:04   ` Joseph Myers
  0 siblings, 0 replies; 6+ messages in thread
From: Joseph Myers @ 2024-01-04 20:04 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Florian Weimer, Jakub Jelinek

On Thu, 4 Jan 2024, Adhemerval Zanella wrote:

> @@ -748,13 +760,19 @@ __bc32_inline (uint32_t __x)
>  static __always_inline uint16_t
>  __bc16_inline (uint16_t __x)
>  {
> -  return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) - 1);
> +  return (uint16_t) (__x <= 1
> +		     ? 1
> +		     : ((uint16_t) 2)
> +			<< (__bw16_inline ((uint16_t) (__x - 1)) - 1));
>  }
>  
>  static __always_inline uint8_t
>  __bc8_inline (uint8_t __x)
>  {
> -  return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);
> +  return (uint8_t) (__x <= 1
> +		    ? 1
> +		    : ((uint8_t) 2)
> +		      << (__bw8_inline ((uint8_t) (__x - 1)) - 1));
>  }

Maybe these should use the __pacify macros as well?

-- 
Joseph S. Myers
jsm@polyomino.org.uk

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc
  2024-01-04 19:47 Adhemerval Zanella
@ 2024-01-04 19:47 ` Adhemerval Zanella
  2024-01-04 20:04   ` Joseph Myers
  0 siblings, 1 reply; 6+ messages in thread
From: Adhemerval Zanella @ 2024-01-04 19:47 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joseph Myers, Florian Weimer, Jakub Jelinek

With gcc 6.5.0, 7.5.0, 8.5.0, and 9.5.0 the tst-stdbit-Wconversion
issues the warnings:

../stdlib/stdbit.h: In function ‘__clo16_inline’:
../stdlib/stdbit.h:128:26: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __clz16_inline (~__x);
                          ^
../stdlib/stdbit.h: In function ‘__clo8_inline’:
../stdlib/stdbit.h:134:25: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __clz8_inline (~__x);
                         ^
../stdlib/stdbit.h: In function ‘__cto16_inline’:
../stdlib/stdbit.h:232:26: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __ctz16_inline (~__x);
                          ^
../stdlib/stdbit.h: In function ‘__cto8_inline’:
../stdlib/stdbit.h:238:25: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __ctz8_inline (~__x);
                         ^
../stdlib/stdbit.h: In function ‘__bf16_inline’:
../stdlib/stdbit.h:701:23: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x == 0 ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1);
          ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../stdlib/stdbit.h: In function ‘__bf8_inline’:
../stdlib/stdbit.h:707:23: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x == 0 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1);
          ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../stdlib/stdbit.h: In function ‘__bc16_inline’:
../stdlib/stdbit.h:751:59: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) -
1);
                                                           ^~~
../stdlib/stdbit.h:751:23: error: conversion to ‘uint16_t {aka short
unsigned int}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) -
1);
          ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../stdlib/stdbit.h: In function ‘__bc8_inline’:
../stdlib/stdbit.h:757:57: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);
                                                         ^~~
../stdlib/stdbit.h:757:23: error: conversion to ‘uint8_t {aka unsigned
char}’ from ‘int’ may alter its value [-Werror=conversion]
   return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);

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.

Checked on x86_64-linux-gnu and i686-linux-gnu with gcc 9.5.0.
---
 stdlib/stdbit.h | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/stdlib/stdbit.h b/stdlib/stdbit.h
index 773b2ab72d..2945550385 100644
--- a/stdlib/stdbit.h
+++ b/stdlib/stdbit.h
@@ -41,6 +41,16 @@
 
 __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.  */
+#if __GNUC_PREREQ (11, 0)
+# define __pacify_uint8(n)  (n)
+# define __pacify_uint16(n) (n)
+#else
+# define __pacify_uint8(n)  ((uint8_t) (n))
+# define __pacify_uint16(n) ((uint16_t) (n))
+#endif
+
 /* Count leading zeros.  */
 extern unsigned int stdc_leading_zeros_uc (unsigned char __x)
      __THROW __attribute_const__;
@@ -125,13 +135,13 @@ __clo32_inline (uint32_t __x)
 static __always_inline unsigned int
 __clo16_inline (uint16_t __x)
 {
-  return __clz16_inline (~__x);
+  return __clz16_inline (__pacify_uint16 (~__x));
 }
 
 static __always_inline unsigned int
 __clo8_inline (uint8_t __x)
 {
-  return __clz8_inline (~__x);
+  return __clz8_inline (__pacify_uint8 (~__x));
 }
 
 # define stdc_leading_ones_uc(x) (__clo8_inline (x))
@@ -229,13 +239,13 @@ __cto32_inline (uint32_t __x)
 static __always_inline unsigned int
 __cto16_inline (uint16_t __x)
 {
-  return __ctz16_inline (~__x);
+  return __ctz16_inline (__pacify_uint16 (~__x));
 }
 
 static __always_inline unsigned int
 __cto8_inline (uint8_t __x)
 {
-  return __ctz8_inline (~__x);
+  return __ctz8_inline (__pacify_uint8 (~__x));
 }
 
 # define stdc_trailing_ones_uc(x) (__cto8_inline (x))
@@ -698,13 +708,15 @@ __bf32_inline (uint32_t __x)
 static __always_inline uint16_t
 __bf16_inline (uint16_t __x)
 {
-  return __x == 0 ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1);
+  return __pacify_uint16 (__x == 0
+			  ? 0 : ((uint16_t) 1) << (__bw16_inline (__x) - 1));
 }
 
 static __always_inline uint8_t
 __bf8_inline (uint8_t __x)
 {
-  return __x == 0 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1);
+  return __pacify_uint8 (__x == 0
+			 ? 0 : ((uint8_t) 1) << (__bw8_inline (__x) - 1));
 }
 
 # define stdc_bit_floor_uc(x) ((unsigned char) __bf8_inline (x))
@@ -748,13 +760,19 @@ __bc32_inline (uint32_t __x)
 static __always_inline uint16_t
 __bc16_inline (uint16_t __x)
 {
-  return __x <= 1 ? 1 : ((uint16_t) 2) << (__bw16_inline (__x - 1) - 1);
+  return (uint16_t) (__x <= 1
+		     ? 1
+		     : ((uint16_t) 2)
+			<< (__bw16_inline ((uint16_t) (__x - 1)) - 1));
 }
 
 static __always_inline uint8_t
 __bc8_inline (uint8_t __x)
 {
-  return __x <= 1 ? 1 : ((uint8_t) 2) << (__bw8_inline (__x - 1) - 1);
+  return (uint8_t) (__x <= 1
+		    ? 1
+		    : ((uint8_t) 2)
+		      << (__bw8_inline ((uint8_t) (__x - 1)) - 1));
 }
 
 # define stdc_bit_ceil_uc(x) ((unsigned char) __bc8_inline (x))
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-01-05 17:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-05 17:17 [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion Adhemerval Zanella
2024-01-05 17:17 ` [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc Adhemerval Zanella
2024-01-05 17:17 ` [PATCH 2/2] stdlib: Fix stdbit.h with -Wconversion for clang Adhemerval Zanella
2024-01-05 17:31 ` [PATCH 0/2] stdlib: Fix stdbit.h with -Wconversion Joseph Myers
  -- strict thread matches above, loose matches on Subject: below --
2024-01-04 19:47 Adhemerval Zanella
2024-01-04 19:47 ` [PATCH 1/2] stdlib: Fix stdbit.h with -Wconversion for older gcc Adhemerval Zanella
2024-01-04 20:04   ` Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).