From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1791) id 187F93857BA7; Fri, 5 Jan 2024 17:53:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 187F93857BA7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1704477183; bh=T+hsBeqqErfDc1x0q4F/G5Mm7ZiB4xSksxs8FBxLqbA=; h=From:To:Subject:Date:From; b=cd77WYrCAPkw0NDeiq96rh+TAQAKK8bpi2QfomClQc0p/rBEa7X4SnWP0bh/p80L7 KK4a3CyjVBWplScOaVcMMJpfyEOrKAUkGw2C4sN5UKU0UXHlGrjnwi+HaJ7JpC5P3F 7NVA4uuvGO6AGilD7DANcnb0wVRbqtU1AinMWtbE= MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: Adhemerval Zanella To: glibc-cvs@sourceware.org Subject: [glibc] stdlib: Fix stdbit.h with -Wconversion for older gcc X-Act-Checkin: glibc X-Git-Author: Adhemerval Zanella X-Git-Refname: refs/heads/master X-Git-Oldrev: 848746e88ec2aa22e8dea25f2110e2b2c59c712e X-Git-Newrev: c8e31fbf0475fd8e8684ead93360e1f069c11426 Message-Id: <20240105175303.187F93857BA7@sourceware.org> Date: Fri, 5 Jan 2024 17:53:03 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c8e31fbf0475fd8e8684ead93360e1f069c11426 commit c8e31fbf0475fd8e8684ead93360e1f069c11426 Author: Adhemerval Zanella 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))