From 8b7b159bcc39fe17f1dab8a9692f73694e1d9a70 Mon Sep 17 00:00:00 2001 From: Ranier Vilela Date: Sat, 29 Jul 2023 09:17:50 -0300 Subject: [PATCH] Avoid undefined behavior with msvc compiler. [1] msvc documentation says: [out] Loaded with the bit position of the first set bit (1) found. Otherwise, undefined. _BitScanReverse and _BitScanReverse64 really need check return value. Because both can functions fails in search of bit index. More with msvc compiler the current implementation lacks assertion checks the input parameter. Author: Ranier Vilela (ranier.vf@gmail.com) [1] https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64?view=msvc-170 --- src/include/port/pg_bitutils.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 21a4fa0341..d285fb83ec 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -46,11 +46,15 @@ pg_leftmost_one_pos32(uint32 word) return 31 - __builtin_clz(word); #elif defined(_MSC_VER) unsigned long result; - bool non_zero; + unsigned char is_non_zero; - non_zero = _BitScanReverse(&result, word); - Assert(non_zero); - return (int) result; + Assert(word != 0); + + is_non_zero = _BitScanReverse(&result, word); + if (is_non_zero) + return (int) result; + else + return 0; #else int shift = 32 - 8; @@ -83,11 +87,15 @@ pg_leftmost_one_pos64(uint64 word) #elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64)) unsigned long result; - bool non_zero; + unsigned char is_non_zero; - non_zero = _BitScanReverse64(&result, word); - Assert(non_zero); - return (int) result; + Assert(word != 0); + + is_non_zero = _BitScanReverse64(&result, word); + if (is_non_zero) + return (int) result; + else + return 0; #else int shift = 64 - 8; -- 2.32.0.windows.1