]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
bits_is_power_of_two() Replace signed expression with __builtin_popcountl()
authorMarco Bettini <marco.bettini@open-xchange.com>
Mon, 29 Nov 2021 14:00:41 +0000 (15:00 +0100)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 30 Nov 2021 10:03:03 +0000 (10:03 +0000)
Found by code analysis tool

src/lib/bits.h
src/lib/test-bits.c

index 586b166e76abd0ab9445ea47688feaeafde8ff90..3b761f11b65d8705539f79f5db2b5ab1532a3e32 100644 (file)
 /* Returns x, such that x is the smallest power of 2 >= num. */
 size_t nearest_power(size_t num) ATTR_CONST;
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+
 /* Returns TRUE if 2^x=num, i.e. if num has only a single bit set to 1. */
 static inline bool ATTR_CONST
 bits_is_power_of_two(uint64_t num)
 {
-       return num > 0 && (num & (num - 1)) == 0;
+       return __builtin_popcountll(num) == 1;
 }
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
 static inline unsigned int ATTR_CONST
 bits_required32(uint32_t num)
 {
@@ -44,7 +45,16 @@ bits_required64(uint64_t num)
 {
        return num == 0 ? 0 : 64 - __builtin_clzll(num);
 }
+
 #else
+
+/* Returns TRUE if 2^x=num, i.e. if num has only a single bit set to 1. */
+static inline bool ATTR_CONST
+bits_is_power_of_two(uint64_t num)
+{
+       return num != 0 && (num & (num + ~0ULL)) == 0;
+}
+
 unsigned int bits_required8(uint8_t num) ATTR_CONST;
 
 static inline
@@ -65,6 +75,7 @@ unsigned int bits_required64(uint64_t num)
        return (num <= 0xffffffff) ? bits_required32(num)
                : 32 + bits_required32(num >> 32);
 }
+
 #endif
 
 static inline uint64_t ATTR_NO_SANITIZE_INTEGER
index 5bdd5a50b849a0eba7bf537c03695223542ee302..c43209aa6b07a9b519ff26c5612c265bda732be7 100644 (file)
@@ -50,6 +50,7 @@ static void test_bits_is_power_of_two(void)
        }
        test_assert(!bits_is_power_of_two(0));
        test_assert(!bits_is_power_of_two(0xffffffffffffffffULL));
+       test_assert( bits_is_power_of_two(0x8000000000000000ULL));
        test_end();
 }