From 98211a2c69037c4402000dc7c8b33bc34a01abb9 Mon Sep 17 00:00:00 2001 From: Khronos31 <39792509+Khronos31@users.noreply.github.com> Date: Sat, 5 Sep 2026 06:13:27 +0900 Subject: [PATCH] Use long int builtins for xtensa (esp) targets (#26170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #25200. `xtensa-esp-elf-gcc` (the ESP-IDF toolchain for the Xtensa ESP32/ESP32-S2/ESP32-S3) defines `int32_t` as `long int`, exactly like `arm-none-eabi-gcc` and `riscv32-unknown-elf-gcc` do: ```console $ xtensa-esp32s3-elf-gcc -dM -E -x c /dev/null | grep -E '__INT32_TYPE__|__SIZEOF_(INT|LONG)__|__xtensa__|__unix__' #define __SIZEOF_INT__ 4 #define __SIZEOF_LONG__ 4 #define __xtensa__ 1 #define __INT32_TYPE__ long int ``` So with `--cpu:esp`, `NI`/`NI32` become `long int` while `nimAddInt` still expands to `__builtin_sadd_overflow`, which expects `int*`: ``` error: passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type [-Wincompatible-pointer-types] note: expected 'int *' but argument is of type 'NI32 *' {aka 'long int *'} ``` This is a warning on GCC 13 and below, but [a hard error since GCC 14](https://gcc.gnu.org/gcc-14/porting_to.html#incompatible-pointer-types) — the log in #25200 shows the build failing outright with the `esp-15.1.0` toolchain. This applies the same fix that #23835 (arm-none-eabi), #24553 (riscv32) and #26121 (limiting arm to non-`__unix__`) already applied, now for Xtensa. The `!defined(__unix__)` guard mirrors #26121: the bare-metal ESP toolchain does not define `__unix__` (verified above), so it is unaffected, while a hypothetical `xtensa-*-linux` target keeps the current `int` behaviour rather than being switched blindly. ### Verification Compiling Nim-generated C for `--cpu:esp --os:standalone` with `xtensa-esp32s3-elf-gcc 12.2.0` and `-Werror=incompatible-pointer-types` (to reproduce the GCC 14+ default): | `lib/nimbase.h` | exit code | `incompatible pointer` diagnostics | |---|---|---| | devel | 1 | 1 | | this PR | 0 | 0 | No effect on any other target: the change is inside the `NIM_INTBITS == 32` branch and is gated on `__xtensa__`. --- lib/nimbase.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/nimbase.h b/lib/nimbase.h index 26fd6751f7..af5d2b9e36 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -598,8 +598,9 @@ 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 - #if ((defined(__arm__) && !defined(__unix__)) || defined(__riscv)) && defined(__GNUC__) - /* arm-none-eabi-gcc and riscv32-unknown-elf-gcc targets define int32_t as long int */ + #if ((defined(__arm__) && !defined(__unix__)) || defined(__riscv) || (defined(__xtensa__) && !defined(__unix__))) && defined(__GNUC__) + /* arm-none-eabi-gcc, riscv32-unknown-elf-gcc and xtensa-esp-elf-gcc targets + define 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)