public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc] stdlib: Fix stdbit.h with -Wconversion for older gcc
@ 2024-01-05 17:53 Adhemerval Zanella
  0 siblings, 0 replies; only message in thread
From: Adhemerval Zanella @ 2024-01-05 17:53 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c8e31fbf0475fd8e8684ead93360e1f069c11426

commit c8e31fbf0475fd8e8684ead93360e1f069c11426
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Thu Jan 4 14:44:42 2024 -0300

    stdlib: Fix stdbit.h with -Wconversion for older gcc
    
    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.

Diff:
---
 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))

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-01-05 17:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-05 17:53 [glibc] stdlib: Fix stdbit.h with -Wconversion for older gcc Adhemerval Zanella

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).