From c04c685469e093520fc2413c1d364c325f88e952 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Wed, 8 May 2024 23:08:33 +0200 Subject: [PATCH] src: restrict upx::atomic_exchange to pointer-size for now --- misc/cmake/try_compile/types_abi.cpp | 8 ++++ src/check/dt_cxxlib.cpp | 55 ++++++++++------------------ src/util/cxxlib.h | 3 ++ 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/misc/cmake/try_compile/types_abi.cpp b/misc/cmake/try_compile/types_abi.cpp index 51393c5f..c24242d9 100644 --- a/misc/cmake/try_compile/types_abi.cpp +++ b/misc/cmake/try_compile/types_abi.cpp @@ -1,14 +1,22 @@ // Copyright (C) Markus Franz Xaver Johannes Oberhumer #include +#include // check ABI - require proper alignment of fundamental types for use in atomics static_assert(alignof(char) == sizeof(char), ""); +static_assert(alignof(signed char) == sizeof(signed char), ""); +static_assert(alignof(unsigned char) == sizeof(unsigned char), ""); static_assert(alignof(short) == sizeof(short), ""); +static_assert(alignof(unsigned short) == sizeof(unsigned short), ""); static_assert(alignof(int) == sizeof(int), ""); +static_assert(alignof(unsigned int) == sizeof(unsigned int), ""); static_assert(alignof(long) == sizeof(long), ""); +static_assert(alignof(unsigned long) == sizeof(unsigned long), ""); static_assert(alignof(ptrdiff_t) == sizeof(ptrdiff_t), ""); static_assert(alignof(size_t) == sizeof(size_t), ""); +static_assert(alignof(intptr_t) == sizeof(intptr_t), ""); +static_assert(alignof(uintptr_t) == sizeof(uintptr_t), ""); static_assert(alignof(void *) == sizeof(void *), ""); int main() { return 0; } diff --git a/src/check/dt_cxxlib.cpp b/src/check/dt_cxxlib.cpp index d5f0533e..872acf0c 100644 --- a/src/check/dt_cxxlib.cpp +++ b/src/check/dt_cxxlib.cpp @@ -252,48 +252,31 @@ struct Z2_X2 : public X2 { #if WITH_THREADS TEST_CASE("upx::ptr_std_atomic_cast") { - (void) upx::ptr_std_atomic_cast((upx_int8_t *) nullptr); - (void) upx::ptr_std_atomic_cast((upx_int16_t *) nullptr); - (void) upx::ptr_std_atomic_cast((upx_int32_t *) nullptr); - (void) upx::ptr_std_atomic_cast((int *) nullptr); - (void) upx::ptr_std_atomic_cast((long *) nullptr); - (void) upx::ptr_std_atomic_cast((ptrdiff_t *) nullptr); - (void) upx::ptr_std_atomic_cast((size_t *) nullptr); - (void) upx::ptr_std_atomic_cast((void **) nullptr); + // pointer-size + CHECK_EQ(upx::ptr_std_atomic_cast((void **) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((uintptr_t *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((upx_uintptr_t *) nullptr), nullptr); +#if 1 + // more fundamental types + CHECK_EQ(upx::ptr_std_atomic_cast((char *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((short *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((int *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((long *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((ptrdiff_t *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((size_t *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((upx_int8_t *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((upx_int16_t *) nullptr), nullptr); + CHECK_EQ(upx::ptr_std_atomic_cast((upx_int32_t *) nullptr), nullptr); +#endif } #endif TEST_CASE("upx::atomic_exchange") { -#if defined(__riscv) -// RISC-V has no support for subword atomic operations and needs libatomic to emulate -#else { - upx_int8_t x = -1; - upx_int8_t y = upx::atomic_exchange(&x, (upx_int8_t) 2); + upx_uintptr_t x = (upx_uintptr_t) 0 - 1; + upx_uintptr_t y = upx::atomic_exchange(&x, (upx_uintptr_t) 2); CHECK_EQ(x, 2); - CHECK_EQ(y, -1); - UNUSED(y); - } - { - upx_int16_t x = -1; - upx_int16_t y = upx::atomic_exchange(&x, (upx_int16_t) 2); - CHECK_EQ(x, 2); - CHECK_EQ(y, -1); - UNUSED(y); - } - { - upx_int32_t x = -1; - upx_int32_t y = upx::atomic_exchange(&x, (upx_int32_t) 2); - CHECK_EQ(x, 2); - CHECK_EQ(y, -1); - UNUSED(y); - } -#endif // __riscv - { - size_t x = (size_t) 0 - 1; - size_t y = upx::atomic_exchange(&x, (size_t) 2); - CHECK_EQ(x, 2); - CHECK_EQ(y, (size_t) 0 - 1); + CHECK_EQ(y, (upx_uintptr_t) 0 - 1); UNUSED(y); } { diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index 0cfdbc5d..42655388 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -204,6 +204,9 @@ forceinline std::atomic *ptr_std_atomic_cast(T *ptr) noexcept { // atomic_exchange template forceinline T atomic_exchange(T *ptr, T new_value) noexcept { +#if 1 + static_assert(sizeof(T) == sizeof(void *)); // UPX convention: restrict to pointer-size for now +#endif static_assert(std::is_standard_layout_v); static_assert(std::is_trivially_copyable_v); #if !(WITH_THREADS)