From 04022a515c76d0acf1ee1147fc4de2cfc12d5c52 Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Mon, 20 Jan 2025 23:42:03 -0800 Subject: [PATCH] Fixes for building with clang-cl on Windows (#104) * Avoid unused-variable warning on Windows When compiling with clang-cl: .../ir_emit.c(275,8): error: unused variable 'handle' [-Werror,-Wunused-variable] 275 | void *handle = NULL; | ^~~~~~ * Avoid redefining __ORDER_LITTLE_ENDIAN__ if already defined clang-cl defines this on Windows, resulting in an error. .../ir.h(32,10): error: '__ORDER_LITTLE_ENDIAN__' macro redefined [-Werror,-Wmacro-redefined] 32 | # define __ORDER_LITTLE_ENDIAN__ 1 | ^ (39,9): note: previous definition is here 39 | #define __ORDER_LITTLE_ENDIAN__ 1234 * In ir_ntzl, always use the 64 bit version on Windows When compiling on Windows with clang-cl, __has_builtin(__builtin_ctzl) will evaluate to true, but a long on Windows is only 32 bits, resulting in an incorrect implementation. Move the _WIN64 block ahead of the general block so that it gets the 64 bit version. Fixes https://github.com/dstogov/ir/issues/101. --- ir.h | 4 +++- ir_emit.c | 2 +- ir_private.h | 9 ++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ir.h b/ir.h index 69a01c21..2670fdfa 100644 --- a/ir.h +++ b/ir.h @@ -29,7 +29,9 @@ extern "C" { # endif /* Only supported is little endian for any arch on Windows, so just fake the same for all. */ -# define __ORDER_LITTLE_ENDIAN__ 1 +# ifndef __ORDER_LITTLE_ENDIAN__ +# define __ORDER_LITTLE_ENDIAN__ 1 +# endif # define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ # ifndef __has_builtin # define __has_builtin(arg) (0) diff --git a/ir_emit.c b/ir_emit.c index 83fc242a..367dee72 100644 --- a/ir_emit.c +++ b/ir_emit.c @@ -272,10 +272,10 @@ static bool ir_is_same_mem_var(const ir_ctx *ctx, ir_ref r1, int32_t offset) void *ir_resolve_sym_name(const char *name) { - void *handle = NULL; void *addr; #ifndef _WIN32 + void *handle = NULL; # ifdef RTLD_DEFAULT handle = RTLD_DEFAULT; # endif diff --git a/ir_private.h b/ir_private.h index 4d1e8dd3..f980b86b 100644 --- a/ir_private.h +++ b/ir_private.h @@ -137,9 +137,10 @@ IR_ALWAYS_INLINE uint32_t ir_ntz(uint32_t num) /* Number of trailing zero bits (0x01 -> 0; 0x40 -> 6; 0x00 -> LEN) */ IR_ALWAYS_INLINE uint32_t ir_ntzl(uint64_t num) { -#if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) - return __builtin_ctzl(num); -#elif defined(_WIN64) + // Note that the _WIN64 case should come before __has_builtin() below so that + // clang-cl on Windows will use the uint64_t version, not the "long" uint32_t + // version. +#if defined(_WIN64) unsigned long index; if (!_BitScanForward64(&index, num)) { @@ -148,6 +149,8 @@ IR_ALWAYS_INLINE uint32_t ir_ntzl(uint64_t num) } return (uint32_t) index; +#elif (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) + return __builtin_ctzl(num); #else uint32_t n;