-/* Licensed under LGPLv2.1+ - see LICENSE file for details */
+/* CC0 (Public domain) - see LICENSE file for details */
#if !defined(_ilog_H)
# define _ilog_H (1)
# include "config.h"
* return 1U << ilog32(i-1);
* }
*/
-int ilog32(uint32_t _v) IDEMPOTENT;
+int ilog32(uint32_t _v) CONST_FUNCTION;
/**
* ilog32_nz - Integer binary logarithm of a non-zero 32-bit value.
* return ilog32_nz(i) - 1;
* }
*/
-int ilog32_nz(uint32_t _v) IDEMPOTENT;
+int ilog32_nz(uint32_t _v) CONST_FUNCTION;
/**
* ilog64 - Integer binary logarithm of a 64-bit value.
* See Also:
* ilog64_nz(), ilog32()
*/
-int ilog64(uint64_t _v) IDEMPOTENT;
+int ilog64(uint64_t _v) CONST_FUNCTION;
/**
* ilog64_nz - Integer binary logarithm of a non-zero 64-bit value.
* See Also:
* ilog64(), ilog32_nz()
*/
-int ilog64_nz(uint64_t _v) IDEMPOTENT;
+int ilog64_nz(uint64_t _v) CONST_FUNCTION;
/**
* STATIC_ILOG_32 - The integer logarithm of an (unsigned, 32-bit) constant.
#endif
#ifdef builtin_ilog32_nz
-#define ilog32(_v) (builtin_ilog32_nz(_v)&-!!(_v))
+/* This used to be builtin_ilog32_nz(_v)&-!!(_v), which means it zeroes out
+ * the undefined builtin_ilog32_nz(0) return. But clang UndefinedBehaviorSantizer
+ * complains, so do the branch: */
+#define ilog32(_v) ((_v) ? builtin_ilog32_nz(_v) : 0)
#define ilog32_nz(_v) builtin_ilog32_nz(_v)
#else
#define ilog32_nz(_v) ilog32(_v)
#endif /* builtin_ilog32_nz */
#ifdef builtin_ilog64_nz
-#define ilog64(_v) (builtin_ilog64_nz(_v)&-!!(_v))
+#define ilog32(_v) ((_v) ? builtin_ilog32_nz(_v) : 0)
#define ilog64_nz(_v) builtin_ilog64_nz(_v)
#else
#define ilog64_nz(_v) ilog64(_v)