Nim icon indicating copy to clipboard operation
Nim copied to clipboard

GCC error`-Wincompatible-pointer-types` with `esp` CPU

Open adokitkat opened this issue 2 months ago • 8 comments

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

adokitkat avatar Sep 29 '25 15:09 adokitkat

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?

elcritch avatar Sep 30 '25 16:09 elcritch

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?

adokitkat avatar Sep 30 '25 22:09 adokitkat

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.

elcritch avatar Sep 30 '25 23:09 elcritch

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 :)

adokitkat avatar Sep 30 '25 23:09 adokitkat

@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?

adokitkat avatar Sep 30 '25 23:09 adokitkat

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 avatar Oct 01 '25 00:10 elcritch

@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?

elcritch avatar Oct 01 '25 00:10 elcritch

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.

tersec avatar Oct 03 '25 04:10 tersec