summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMark Leyva <maleyva1@users.noreply.github.com>2024-08-12 09:10:33 -0700
committerGitHub <noreply@github.com>2024-08-12 18:10:33 +0200
commitc5b206d4ac6704147d9ec27506b9d0171f3a9501 (patch)
treeb2ab541a048a7fd169d7eeff78530b9637de8c01
parent630c304a2dff6be70717224e533c1ad6f01875e3 (diff)
downloadNim-c5b206d4ac6704147d9ec27506b9d0171f3a9501.tar.gz
fix #23817; Use __builtin_saddl_overflow variants for arm-none-eabi-gcc. (#23835)
Provides a fix for #23817. 

With target `arm-none-eabi`, GCC defines `int32_t` to `long int`. Nim
uses `__builtin_sadd_overflow` for 32-bit targets, but this emits
warnings on GCC releases 13 and under, while generating an error on GCC
14. More info regarding this
[here](https://gcc.gnu.org/gcc-14/porting_to.html#c) and
[here](https://gcc.gnu.org/pipermail/gcc-cvs/2023-December/394351.html).

The proposed PR attempts to address this issue for these targets by
defining the `nimAddInt`, `nimSubInt`, and `nimMulInt` macros to use the
appropriate compiler intrinsics for this platform.

As for as we know, the LLVM toolchain for bare metal Arm does not define
`int32_t` as `long int` and has no need for this patch. Thus, we only
define the above macros for GCC targeting `arm-non-eabi`.
-rw-r--r--lib/nimbase.h14
1 files changed, 11 insertions, 3 deletions
diff --git a/lib/nimbase.h b/lib/nimbase.h
index cdbb68ff2..cf0c8002b 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -14,6 +14,7 @@ __GNUC__
 __TINYC__
 __clang__
 __AVR__
+__arm__
 __EMSCRIPTEN__
 */
 
@@ -584,9 +585,16 @@ NIM_STATIC_ASSERT(sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8, "P
   #define nimMulInt64(a, b, res) __builtin_smulll_overflow(a, b, (long long int*)res)
 
   #if NIM_INTBITS == 32
-    #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
-    #define nimSubInt(a, b, res) __builtin_ssub_overflow(a, b, res)
-    #define nimMulInt(a, b, res) __builtin_smul_overflow(a, b, res)
+    #if defined(__arm__) && defined(__GNUC__)
+      /* arm-none-eabi-gcc targets defines int32_t as long int */
+      #define nimAddInt(a, b, res) __builtin_saddl_overflow(a, b, res)
+      #define nimSubInt(a, b, res) __builtin_ssubl_overflow(a, b, res)
+      #define nimMulInt(a, b, res) __builtin_smull_overflow(a, b, res)
+    #else
+      #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
+      #define nimSubInt(a, b, res) __builtin_ssub_overflow(a, b, res)
+      #define nimMulInt(a, b, res) __builtin_smul_overflow(a, b, res)
+    #endif
   #else
     /* map it to the 'long long' variant */
     #define nimAddInt(a, b, res) __builtin_saddll_overflow(a, b, (long long int*)res)