From 71b3c8a35bcdeb9287df9c7e1801c2021daf5ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 11 Jun 2024 22:11:50 +0200 Subject: [PATCH] Force default `char` to be `signed` on all architectures We assume that `char` is `signed` in various places in the code. In particular, the `Str.StrToInts` test will fail when `char` is not `signed` and names containing special characters will be displayed incorrectly on servers. Therefore, the compiler flag `-fsigned-char` is set unconditionally instead of only for ARM and ARM64, as we expect `char` to be `signed` on all architectures. A static assertion is added to ensure at compile time that `char` is `signed` independently from the flag added in `CMakeLists.txt`. This is necessary at least for ARM, ARM64, PPC, PPC64, and PPC64LE. According to some sources, `char` may also be `unsigned` by default when compiling for Android, although this could not be confirmed with the current Android NDK using Clang. For the PowerPC architectures, Compiler Explorer can be used to confirm that `char` is not `signed` by default by checking whether the static assertion compiles (see https://godbolt.org/z/9rn5Mrf59) and that the assembly is different with the `-fsigned-char` flag (see https://godbolt.org/z/138zTj3Wa). Closes #8386. --- CMakeLists.txt | 9 ++++----- src/game/gamecore.cpp | 4 ++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a10762c32..71e625e54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -291,11 +291,10 @@ if(NOT MSVC AND NOT HAIKU) add_cxx_compiler_flag_if_supported(OUR_FLAGS -ffloat-store) endif() - # This is needed to get the server to correctly display special characters - # on ARM systems. - if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm" OR "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64") - add_cxx_compiler_flag_if_supported(OUR_FLAGS -fsigned-char) - endif() + # We assume that char is signed in various places in the code. In particular, + # the Str.StrToInts test will fail when char is not signed and names containing + # special characters will be displayed incorrectly on servers. + add_cxx_compiler_flag_if_supported(OUR_FLAGS -fsigned-char) # Don't insert timestamps into PEs to keep the build reproducible. if(TARGET_OS STREQUAL "windows") diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index fad18b7ac..0f37382b0 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -9,6 +9,8 @@ #include #include +#include + const char *CTuningParams::ms_apNames[] = { #define MACRO_TUNING_PARAM(Name, ScriptName, Value, Description) #ScriptName, @@ -63,6 +65,8 @@ float CTuningParams::GetWeaponFireDelay(int Weapon) const } } +static_assert(std::numeric_limits::is_signed, "char must be signed for StrToInts to work correctly"); + void StrToInts(int *pInts, size_t NumInts, const char *pStr) { dbg_assert(NumInts > 0, "StrToInts: NumInts invalid");