fix build on msvc in C compilation; fix build with clang-cl on Windows

This commit is contained in:
Daan Leijen 2025-01-06 10:27:46 -08:00
parent 9ec5da08b2
commit 5764845c4d
4 changed files with 37 additions and 26 deletions

View file

@ -102,10 +102,17 @@ endif()
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Process options # Process options
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(MI_CLANG_CL "ON")
endif()
# put -Wall early so other warnings can be disabled selectively # put -Wall early so other warnings can be disabled selectively
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang") if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang")
list(APPEND mi_cflags -Wall -Wextra -Wpedantic) if (MI_CLANG_CL)
list(APPEND mi_cflags -W)
else()
list(APPEND mi_cflags -Wall -Wextra -Wpedantic)
endif()
endif() endif()
if(CMAKE_C_COMPILER_ID MATCHES "GNU") if(CMAKE_C_COMPILER_ID MATCHES "GNU")
list(APPEND mi_cflags -Wall -Wextra) list(APPEND mi_cflags -Wall -Wextra)
@ -371,7 +378,7 @@ endif()
# endif() # endif()
# Compiler flags # Compiler flags
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU" AND NOT MI_CLANG_CL)
list(APPEND mi_cflags -Wno-unknown-pragmas -fvisibility=hidden) list(APPEND mi_cflags -Wno-unknown-pragmas -fvisibility=hidden)
if(NOT MI_USE_CXX) if(NOT MI_USE_CXX)
list(APPEND mi_cflags -Wstrict-prototypes) list(APPEND mi_cflags -Wstrict-prototypes)
@ -385,7 +392,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
list(APPEND mi_cflags -fvisibility=hidden) list(APPEND mi_cflags -fvisibility=hidden)
endif() endif()
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM_NAME MATCHES "Haiku") if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM_NAME MATCHES "Haiku" AND NOT MI_CLANG_CL)
if(MI_LOCAL_DYNAMIC_TLS) if(MI_LOCAL_DYNAMIC_TLS)
list(APPEND mi_cflags -ftls-model=local-dynamic) list(APPEND mi_cflags -ftls-model=local-dynamic)
else() else()
@ -401,6 +408,9 @@ if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM
if(MI_OVERRIDE) if(MI_OVERRIDE)
list(APPEND mi_cflags -fno-builtin-malloc) list(APPEND mi_cflags -fno-builtin-malloc)
endif() endif()
endif()
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM_NAME MATCHES "Haiku")
if(MI_OPT_ARCH) if(MI_OPT_ARCH)
if(MI_ARCH STREQUAL "arm64") if(MI_ARCH STREQUAL "arm64")
set(MI_OPT_ARCH_FLAGS "-march=armv8.1-a") # fast atomics set(MI_OPT_ARCH_FLAGS "-march=armv8.1-a") # fast atomics
@ -410,7 +420,7 @@ endif()
if (MSVC AND MSVC_VERSION GREATER_EQUAL 1914) if (MSVC AND MSVC_VERSION GREATER_EQUAL 1914)
list(APPEND mi_cflags /Zc:__cplusplus) list(APPEND mi_cflags /Zc:__cplusplus)
if(MI_OPT_ARCH) if(MI_OPT_ARCH AND NOT MI_CLANG_CL)
if(MI_ARCH STREQUAL "arm64") if(MI_ARCH STREQUAL "arm64")
set(MI_OPT_ARCH_FLAGS "/arch:armv8.1") # fast atomics set(MI_OPT_ARCH_FLAGS "/arch:armv8.1") # fast atomics
endif() endif()

View file

@ -31,33 +31,33 @@ terms of the MIT license. A copy of the license can be found in the file
#if defined(__cplusplus) #if defined(__cplusplus)
// Use C++ atomics // Use C++ atomics
#include <atomic> #include <atomic>
#define _Atomic(tp) std::atomic<tp> #define _Atomic(tp) std::atomic<tp>
#define mi_atomic(name) std::atomic_##name #define mi_atomic(name) std::atomic_##name
#define mi_memory_order(name) std::memory_order_##name #define mi_memory_order(name) std::memory_order_##name
#if (__cplusplus >= 202002L) // c++20, see issue #571 #if (__cplusplus >= 202002L) // c++20, see issue #571
#define MI_ATOMIC_VAR_INIT(x) x #define MI_ATOMIC_VAR_INIT(x) x
#elif !defined(ATOMIC_VAR_INIT) #elif !defined(ATOMIC_VAR_INIT)
#define MI_ATOMIC_VAR_INIT(x) x #define MI_ATOMIC_VAR_INIT(x) x
#else #else
#define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
#endif #endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
// Use MSVC C wrapper for C11 atomics // Use MSVC C wrapper for C11 atomics
#define _Atomic(tp) tp #define _Atomic(tp) tp
#define MI_ATOMIC_VAR_INIT(x) x #define MI_ATOMIC_VAR_INIT(x) x
#define mi_atomic(name) mi_atomic_##name #define mi_atomic(name) mi_atomic_##name
#define mi_memory_order(name) mi_memory_order_##name #define mi_memory_order(name) mi_memory_order_##name
#else #else
// Use C11 atomics // Use C11 atomics
#include <stdatomic.h> #include <stdatomic.h>
#define mi_atomic(name) atomic_##name #define mi_atomic(name) atomic_##name
#define mi_memory_order(name) memory_order_##name #define mi_memory_order(name) memory_order_##name
#if (__STDC_VERSION__ >= 201710L) // c17, see issue #735 #if (__STDC_VERSION__ >= 201710L) // c17, see issue #735
#define MI_ATOMIC_VAR_INIT(x) x #define MI_ATOMIC_VAR_INIT(x) x
#elif !defined(ATOMIC_VAR_INIT) #elif !defined(ATOMIC_VAR_INIT)
#define MI_ATOMIC_VAR_INIT(x) x #define MI_ATOMIC_VAR_INIT(x) x
#else #else
#define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
#endif #endif
#endif #endif
@ -290,6 +290,7 @@ static inline bool mi_atomic_casi64_strong_acq_rel(volatile _Atomic(int64_t*)p,
#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) #define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) #define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) #define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
#define mi_atomic_exchange_ptr_relaxed(tp,p,x) (tp*)mi_atomic_exchange_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)x)
#define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x) #define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x)
#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x) #define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x)

View file

@ -603,7 +603,7 @@ static void mi_arenas_try_purge( bool force, bool visit_all )
// check if any arena needs purging? // check if any arena needs purging?
const mi_msecs_t now = _mi_clock_now(); const mi_msecs_t now = _mi_clock_now();
mi_msecs_t arenas_expire = mi_atomic_load_acquire(&mi_arenas_purge_expire); mi_msecs_t arenas_expire = mi_atomic_loadi64_acquire(&mi_arenas_purge_expire);
if (!force && (arenas_expire == 0 || arenas_expire < now)) return; if (!force && (arenas_expire == 0 || arenas_expire < now)) return;
const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count); const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count);
@ -614,7 +614,7 @@ static void mi_arenas_try_purge( bool force, bool visit_all )
mi_atomic_guard(&purge_guard) mi_atomic_guard(&purge_guard)
{ {
// increase global expire: at most one purge per delay cycle // increase global expire: at most one purge per delay cycle
mi_atomic_store_release(&mi_arenas_purge_expire, now + mi_arena_purge_delay()); mi_atomic_storei64_release(&mi_arenas_purge_expire, now + mi_arena_purge_delay());
size_t max_purge_count = (visit_all ? max_arena : 2); size_t max_purge_count = (visit_all ? max_arena : 2);
bool all_visited = true; bool all_visited = true;
for (size_t i = 0; i < max_arena; i++) { for (size_t i = 0; i < max_arena; i++) {
@ -631,7 +631,7 @@ static void mi_arenas_try_purge( bool force, bool visit_all )
} }
if (all_visited) { if (all_visited) {
// all arena's were visited and purged: reset global expire // all arena's were visited and purged: reset global expire
mi_atomic_store_release(&mi_arenas_purge_expire, 0); mi_atomic_storei64_release(&mi_arenas_purge_expire, 0);
} }
} }
} }

View file

@ -173,7 +173,7 @@ int _mi_prim_free(void* addr, size_t size ) {
// In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside
// the memory region returned by VirtualAlloc; in that case we need to free using // the memory region returned by VirtualAlloc; in that case we need to free using
// the start of the region. // the start of the region.
MEMORY_BASIC_INFORMATION info = { 0 }; MEMORY_BASIC_INFORMATION info; _mi_memzero_var(info);
VirtualQuery(addr, &info, sizeof(info)); VirtualQuery(addr, &info, sizeof(info));
if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < (ptrdiff_t)MI_SEGMENT_SIZE) { if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < (ptrdiff_t)MI_SEGMENT_SIZE) {
errcode = 0; errcode = 0;