From 07bf3179f6d51a0e80fc48f06490f4e4d0d8488d Mon Sep 17 00:00:00 2001 From: stijn Date: Mon, 22 Jul 2024 13:41:02 +0200 Subject: [PATCH] py/misc: Fix msvc and C++ compatibility. Use explicit casts to suppress warnings about implicit conversions, add a workaround for constant expression conditional, and make functions static inline (as is done in the rest of the codebase) to suppress 'warning C4505: unreferenced function with internal linkage has been removed'. (Follow up to fix commit 908ab1ceca15ee6fd0ef82ca4cba770a3ec41894) Signed-off-by: stijn --- py/misc.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/py/misc.h b/py/misc.h index cf1810d4e784..96b13c151a6b 100644 --- a/py/misc.h +++ b/py/misc.h @@ -338,38 +338,44 @@ typedef const char *mp_rom_error_text_t; #ifdef _MSC_VER #include -static uint32_t mp_clz(uint32_t x) { +static inline uint32_t mp_clz(uint32_t x) { unsigned long lz = 0; return _BitScanReverse(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; } -static uint32_t mp_clzl(unsigned long x) { +static inline uint32_t mp_clzl(unsigned long x) { unsigned long lz = 0; return _BitScanReverse(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; } #ifdef _WIN64 -static uint32_t mp_clzll(unsigned long long x) { +static inline uint32_t mp_clzll(unsigned long long x) { unsigned long lz = 0; return _BitScanReverse64(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; } #else // Microsoft don't ship _BitScanReverse64 on Win32, so emulate it -static uint32_t mp_clzll(unsigned long long x) { +static inline uint32_t mp_clzll(unsigned long long x) { unsigned long h = x >> 32; return h ? mp_clzl(h) : (mp_clzl(x) + 32); } #endif -static uint32_t mp_ctz(uint32_t x) { +static inline uint32_t mp_ctz(uint32_t x) { unsigned long tz = 0; return _BitScanForward(&tz, x) ? tz : 0; } + +// Workaround for 'warning C4127: conditional expression is constant'. +static inline bool mp_check(bool value) { + return value; +} #else #define mp_clz(x) __builtin_clz(x) #define mp_clzl(x) __builtin_clzl(x) #define mp_clzll(x) __builtin_clzll(x) #define mp_ctz(x) __builtin_ctz(x) +#define mp_check(x) (x) #endif // mp_int_t can be larger than long, i.e. Windows 64-bit, nan-box variants @@ -378,10 +384,10 @@ static inline uint32_t mp_clz_mpi(mp_int_t x) { || sizeof(mp_int_t) == sizeof(long)); // ugly, but should compile to single intrinsic unless O0 is set - if (sizeof(mp_int_t) == sizeof(long)) { - return mp_clzl(x); + if (mp_check(sizeof(mp_int_t) == sizeof(long))) { + return mp_clzl((unsigned long)x); } else { - return mp_clzll(x); + return mp_clzll((unsigned long long)x); } }