GCC error`-Wincompatible-pointer-types` with `esp` CPU
Nim Version
Nim Compiler Version 2.3.1 [Linux: amd64] Compiled at 2025-09-25 Copyright (c) 2006-2025 by Andreas Rumpf
git hash: 9f74712ec6ec346f8f1366c10f752d0a9aa85a70 active boot switches: -d:release
as well as
Nim Compiler Version 2.2.4 [Linux: amd64] Compiled at 2025-04-22 Copyright (c) 2006-2025 by Andreas Rumpf
git hash: f7145dd26efeeeb6eeae6fff649db244d81b212d active boot switches: -d:release
OS: WSL2 Ubuntu in Windows 11
Description
I have a special config.nims file for compiling Nim to ESP32 (Xtensa) architecture.
Here is the relevant part:
# Xtensa CPU
switch "cpu", "esp"
switch "passC", "-mlongcalls -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero"
switch "passC", "-Wno-frame-address"
This has worked before, but it doesn't now - this is probably because of changes in GCC? My GCC version si 15.1.0 (using Xtensa GCC from ESP-IDF toolchain).
Current Output
> nimble prepare --verbose
Info: Package cache path /home/ado_linux/.nimble/pkgcache
Info: Nimble data file "/home/ado_linux/.nimble/nimbledata2.json" has been loaded.
Info: Dependency on nim@>= 1.0.0 already satisfied
Info: Dependency on nim@>= 1.6.0 already satisfied
Info: Dependency on unicodedb@>= 0.13.2 already satisfied
Info: Dependency on nim@>= 1.6.2 already satisfied
Info: Dependency on regex@>= 0.19.0 already satisfied
Attempting to execute hook prepareBefore in /home/ado_linux/esp/esp-idf_nim_template/esp_idf_nim_template.nimble
Executing task prepare in /home/ado_linux/esp/esp-idf_nim_template/esp_idf_nim_template.nimble
Using toolchain version: esp-15.1.0_20250607
Hint: used config file '/home/ado_linux/.choosenim/toolchains/nim-#devel/config/nim.cfg' [Conf]
Hint: used config file '/home/ado_linux/.choosenim/toolchains/nim-#devel/config/config.nims' [Conf]
Hint: used config file '/home/ado_linux/esp/esp-idf_nim_template/config.nims' [Conf]
..............................................................
CC: system/exceptions.nim
CC: std/private/digitsutils.nim
CC: std/private/dragonbox.nim
CC: std/private/schubfach.nim
CC: std/formatfloat.nim
CC: system/dollars.nim
CC: system.nim
CC: libnim.nim
In file included from /home/ado_linux/esp/esp-idf_nim_template/main/nimcache/@pstd@[email protected]:128:
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/strs_v2.nim: In function 'nimAddCharV1':
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/strs_v2.nim:93:39: error: passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
93 | inc s.len
| ^
| |
| NI * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/strs_v2.nim:93:39: note: expected 'int *' but argument is of type 'NI *' {aka 'long int *'}
93 | inc s.len
| ^
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim: In function '_ZN11digitsutils8addCharsE3varI6stringE5arrayI8range0234charE3int3int':
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim:45:29: error: passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
45 | result.setLen old + n
| ^
| |
| NI * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim:45:29: note: expected 'int *' but argument is of type 'NI *' {aka 'long int *'}
45 | result.setLen old + n
| ^
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim: In function '_ZN11digitsutils10addIntImplE3varI6stringE6uInt64':
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim:72:37: error: passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
72 | # process last 1-2 digits
| ^
| |
| NI * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim:72:37: note: expected 'int *' but argument is of type 'NI *' {aka 'long int *'}
72 | # process last 1-2 digits
| ^
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
compilation terminated due to -fmax-errors=3.
Error: execution of an external compiler program '/home/ado_linux/.espressif/tools/xtensa-esp-elf/esp-15.1.0_20250607/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc -c -w -fmax-errors=3 -fno-strict-aliasing -mlongcalls -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -g3 -Og -Os -fno-ident -I'/home/ado_linux/.choosenim/toolchains/nim-#devel/lib' -I/home/ado_linux/esp/esp-idf_nim_template/main -o /home/ado_linux/esp/esp-idf_nim_template/main/nimcache/@pstd@[email protected] /home/ado_linux/esp/esp-idf_nim_template/main/nimcache/@pstd@[email protected]' failed with exit code: 1
In file included from /home/ado_linux/esp/esp-idf_nim_template/main/nimcache/@[email protected]:128:
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim: In function '_ZN11digitsutils11utoa2DigitsE3varI9openArrayI4charEE3int6uInt32':
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim:34:34: error: passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
34 | buf[pos+1] = digits100[2 * digits + 1]
| ~^~~~~~~
| |
| NI * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim:34:34: note: expected 'int *' but argument is of type 'NI *' {aka 'long int *'}
34 | buf[pos+1] = digits100[2 * digits + 1]
| ~^~~~~~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
stack trace: (most recent call last)
/tmp/nimblecache-7250407160657696389/nimscriptapi_4880102100347668418.nim(219, 16)
/home/ado_linux/esp/esp-idf_nim_template/esp_idf_nim_template.nimble(15, 5) prepareTask
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/nimscript.nim(264, 7) exec
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/nimscript.nim(264, 7) Error: unhandled exception: FAILED: nim c main/libnim.nim [OSError]
nimscriptwrapper.nim(166) execScript
In file included from /home/ado_linux/esp/esp-idf_nim_template/main/nimcache/@mlibnim.nim.c:128:
/home/ado_linux/esp/esp-idf_nim_template/main/libnim.nim: In function 'add_int_in_nim':
Error: Exception raised during nimble script execution
/home/ado_linux/esp/esp-idf_nim_template/main/libnim.nim:4:28: error: passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
4 | result = a + b
| ^
| |
| NI32 * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/esp/esp-idf_nim_template/main/libnim.nim:4:28: note: expected 'int *' but argument is of type 'NI32 *' {aka 'long int *'}
4 | result = a + b
| ^
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
Info: Nimble data file "/home/ado_linux/.nimble/nimbledata2.json" has been saved.
In file included from /home/ado_linux/esp/esp-idf_nim_template/main/nimcache/@psystem.nim.c:128:
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/iterators_1.nim: In function '_ZN6system18collectCyclesBaconE3varIN6system5GcEnvEE3int':
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/iterators_1.nim:39:33: error: passing argument 3 of '__builtin_ssub_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
39 | dec(res, step)
| ^
| |
| NI * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:607:66: note: in definition of macro 'nimSubInt'
607 | #define nimSubInt(a, b, res) __builtin_ssub_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/iterators_1.nim:39:33: note: expected 'int *' but argument is of type 'NI *' {aka 'long int *'}
39 | dec(res, step)
| ^
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:607:66: note: in definition of macro 'nimSubInt'
607 | #define nimSubInt(a, b, res) __builtin_ssub_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/iterators_1.nim:39:33: error: passing argument 3 of '__builtin_ssub_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
39 | dec(res, step)
| ^
| |
| NI * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:607:66: note: in definition of macro 'nimSubInt'
607 | #define nimSubInt(a, b, res) __builtin_ssub_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/iterators_1.nim:39:33: note: expected 'int *' but argument is of type 'NI *' {aka 'long int *'}
39 | dec(res, step)
| ^
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:607:66: note: in definition of macro 'nimSubInt'
607 | #define nimSubInt(a, b, res) __builtin_ssub_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/iterators_1.nim:131:31: error: passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type [-Wincompatible-pointer-types]
131 | inc i
| ^
| |
| NI * {aka long int *}
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/system/iterators_1.nim:131:31: note: expected 'int *' but argument is of type 'NI *' {aka 'long int *'}
131 | inc i
| ^
/home/ado_linux/.choosenim/toolchains/nim-#devel/lib/nimbase.h:606:66: note: in definition of macro 'nimAddInt'
606 | #define nimAddInt(a, b, res) __builtin_sadd_overflow(a, b, res)
| ^~~
compilation terminated due to -fmax-errors=3.
Expected Output
compile OK
Known Workarounds
Using switch "passC", "-Wno-incompatible-pointer-types" suppresses the errors and compilation completes.
Additional Information
My config for RISC-V ESPs seems to work OK. Here is repo where all the code lives: https://github.com/adokitkat/esp-idf_nim_template
The whole config.nims file (there is also esptarget.nims file which loads some information like GCC path, etc.):
import os, strformat
include "esptarget.nims"
let gcc_exe = gcc_target & "-gcc"
switch "gcc.path", gcc_path
switch "gcc.exe", gcc_exe
switch "gcc.linkerexe", gcc_exe
import strutils
if target == "esp32" or "esp32s" in target:
# Xtensa CPU
switch "cpu", "esp"
switch "passC", "-mlongcalls -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero"
if target == "esp32":
switch "passC", "-Wno-frame-address"
# Workaround for newer GCC versions (14+?)
#switch "passC", "-Wno-incompatible-pointer-types"
else:
# RISC-V CPU
switch "cpu", "riscv32"
switch "passC", "-mtune=esp-base"
if target in ["esp32c2", "esp32c3"]:
switch "passC", "-march=rv32imc_zicsr_zifencei"
elif target in ["esp32c5", "esp32c6", "esp32c61", "esp32h2", "esp32h21"]:
switch "passC", "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc"
elif target in ["esp32h4"]:
switch "passC", "-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xespdsp"
switch "passC", "-mabi=ilp32f"
elif target in ["esp32p4"]:
var esp32p4_rev = ""
const esp32p4_rev_rx: Regex= re"(# CONFIG_ESP32P4_SELECTS_REV_LESS_V3)"
for m in sdkconfig.findAll(esp32p4_rev_rx):
esp32p4_rev = m.groupFirstCapture(0, sdkconfig)
break
if esp32p4_rev == "":
switch "passC", "-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xesploop_xespv2p1" # ESP32-P4 rev. 2 and earlier
else:
switch "passC", "-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_zcb_zcmp_zcmt_xesploop_xespv -mno-cm-popret -mno-cm-push-reverse" # ESP32-P4 rev. 3+
switch "passC", "-mabi=ilp32f"
switch "os", "freertos"
switch "mm", "orc"
switch "threads", "off"
switch "define", "release"
switch "opt", "size"
switch "out", "main/libnim.a"
switch "define", "nimAdaptiveOrc"
switch "define", "use_malloc"
switch "define", "no_signal_handler"
switch "debugger", "native"
switch "tls_emulation", "off"
switch "app", "staticLib"
switch "noMain"
switch "header"
switch "nimcache", "main/nimcache"
switch "forceBuild"
# begin Nimble config (version 2)
when withDir(thisDir(), system.fileExists("nimble.paths")):
include "nimble.paths"
# end Nimble config
Yeah I believe GCC 15 made incompatible-pointer a default error or made it more strict.
I updated Nesper to idf-5.5 and got similar issues.
BTW, do you compile to a static lib and link into IDF cmake outputs or just compile the whole project with Nim?
Hi @elcritch. I compile the Nim code to a static library and then cmake links it to an ESP-IDF project binary. You can see how it's done here https://github.com/adokitkat/esp-idf_nim_template .
How can I compile the whole project using Nim? Or do you mean using Nesper?
Hi @elcritch. I compile the Nim code to a static library and then cmake links it to an ESP-IDF project binary. You can see how it's done here https://github.com/adokitkat/esp-idf_nim_template .
Thanks! I've wondered about trying that route. How well does it work?
How can I compile the whole project using Nim? Or do you mean using Nesper?
I don't know how to do that and thought maybe you did! ;)
Nesper just compiles to C then runs idf.py build. I recently updated the build tasks for Nesper though to simplify them using config.nims. Though maybe I'll add in an option for static libs.
Oh I'd also added -Wno-incompatible-pointer-types to the CMake properties.
It is a proof of concept, a template, I haven't tried anything more complex really 😅 But I don't see why it wouldn't work alright.
I made it quite some time ago, I just revisited and updated it (it was broken due to changes at IDF side plus I fixed and added compile flags for all RISC-V chips). Normally I just use C with ESPs but I might try to do something more interesting using Nim later :)
@elcritch I see you used "cpu arm", why is that? I use esp or riscv32 in my configs file. EDIT: I guess it doesn't matter, I briefly looked at Nim compiler code and they all have attributes with the same values.
Also is it ok to use threads: on?
It is a proof of concept, a template, I haven't tried anything more complex really 😅 But I don't see why it wouldn't work alright.
Nice! I think Github Templates are a great way to setup examples.
I made it quite some time ago, I just revisited and updated it (it was broken due to changes at IDF side plus I fixed and added compile flags for all RISC-V chips). Normally I just use C with ESPs but I might try to do something more interesting using Nim later :)
It's pretty nice once you get used to it! If you try out Nesper feel free to ping me with any questions/problems.
It's awesome being able to run https://github.com/elcritch/fastrpc to get easy RPC calls.
Also is it ok to use threads: on?
Yep! Though I'd recommend using https://github.com/nim-lang/threading for threading stuffs. You can also use xQueue and all that as well which should be wrapped in Nesper.
@elcritch I see you used "cpu arm", why is that? I use esp or riscv32 in my configs file. EDIT: I guess it doesn't matter, I briefly looked at Nim compiler code and they all have attributes with the same values.
Oh do I? Eh yeah I should probably select esp (really it should be xtensa but eh). Really it doesn't matter too much as long as it's 32-bit.
Speaking of that, this issue might be able to be closed? IMHO, fixing it in the compiler isn't really needed. Unless it could be linked to an issue on emitting-C-compatible-types if there is one?
Yeah I believe GCC 15 made incompatible-pointer a default error or made it more strict.
https://gcc.gnu.org/gcc-14/porting_to.html#incompatible-pointer-types did this.