From: Adhemerval Zanella Date: Fri, 25 Apr 2025 17:28:22 +0000 (-0300) Subject: string: Remove UB on ffs/ffsll X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da2b1f328eadc9e242212cff6c2b627d97392344;p=thirdparty%2Fglibc.git string: Remove UB on ffs/ffsll Building with ubsan on 32 bit architecture, tst-ffs shows: ffsll(0x4000000000000000) as expected 63 UBSAN: Undefined behaviour in ffsll.c:37:34 negation of 9223372036854775808 cannot be represented in type 'long long int' Since the idea is to isolate the least significant bit, use unsigned types. --- diff --git a/string/ffs.c b/string/ffs.c index a2aa5b1242..eda9f49197 100644 --- a/string/ffs.c +++ b/string/ffs.c @@ -40,7 +40,9 @@ __ffs (int i) 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 }; unsigned int a; - unsigned int x = i & -i; + /* Isolate the least significant one. */ + unsigned int u_i = i; + unsigned int x = u_i & -u_i; a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24); diff --git a/string/ffsll.c b/string/ffsll.c index 1b01d8fb12..ed2c877ad0 100644 --- a/string/ffsll.c +++ b/string/ffsll.c @@ -29,7 +29,9 @@ __ffsll (long long int i) #if USE_FFSLL_BUILTIN return __builtin_ffsll (i); #else - unsigned long long int x = i & -i; + /* Isolate the least significant one. */ + unsigned long long int i_u = i; + unsigned long long int x = i_u & -i_u; if (x <= 0xffffffff) return ffs (i);