From: Adhemerval Zanella Date: Tue, 22 Apr 2025 17:34:27 +0000 (-0300) Subject: string: Fix UB on index_first/index_last X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21d50c555f48b24368e4c61e4273dda532b397b2;p=thirdparty%2Fglibc.git string: Fix UB on index_first/index_last Building with ubsan the test-strcnmp triggers: UBSAN: Undefined behaviour in ../sysdeps/generic/string-fzi.h:39:12 passing zero to __builtin_ctz() Use stdbit.h functions instead of ctl/clz. --- diff --git a/sysdeps/generic/string-fzi.h b/sysdeps/generic/string-fzi.h index 3c1028d1ec..f90f662ac2 100644 --- a/sysdeps/generic/string-fzi.h +++ b/sysdeps/generic/string-fzi.h @@ -19,28 +19,11 @@ #ifndef _STRING_FZI_H #define _STRING_FZI_H 1 +#include #include #include #include -static __always_inline int -clz (find_t c) -{ - if (sizeof (find_t) == sizeof (unsigned long)) - return __builtin_clzl (c); - else - return __builtin_clzll (c); -} - -static __always_inline int -ctz (find_t c) -{ - if (sizeof (find_t) == sizeof (unsigned long)) - return __builtin_ctzl (c); - else - return __builtin_ctzll (c); -} - /* A subroutine for the index_zero functions. Given a test word C, return the (memory order) index of the first byte (in memory order) that is non-zero. */ @@ -49,9 +32,9 @@ index_first (find_t c) { int r; if (__BYTE_ORDER == __LITTLE_ENDIAN) - r = ctz (c); + r = stdc_trailing_zeros (c); else - r = clz (c); + r = stdc_leading_zeros (c); return r / CHAR_BIT; } @@ -62,9 +45,9 @@ index_last (find_t c) { int r; if (__BYTE_ORDER == __LITTLE_ENDIAN) - r = clz (c); + r = stdc_leading_zeros (c); else - r = ctz (c); + r = stdc_trailing_zeros (c); return sizeof (find_t) - 1 - (r / CHAR_BIT); }