From 21d50c555f48b24368e4c61e4273dda532b397b2 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 22 Apr 2025 14:34:27 -0300 Subject: [PATCH] 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. --- sysdeps/generic/string-fzi.h | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) 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); } -- 2.47.2