nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.42k stars 1.47k forks source link

type-aliased `seq[T]` get different backend C/C++ pointer type names causing invalid codegen on gcc-14 | g++ | clang++ #23923

Closed c-blake closed 2 weeks ago

c-blake commented 1 month ago

Description

type
  Uid* = cuint
  Gid* = cuint

proc usrToUid*(usr: string): Uid = 999.Uid

proc usrToUid*(usrs: seq[string]): seq[Uid] =
  for usr in usrs: result.add usrToUid(usr)

proc grpToGid*(grp: string): Gid = 999.Gid

proc grpToGid*(grps: seq[string]): seq[Gid] =
  for grp in grps: result.add grpToGid(grp)

if grpToGid(@["hi"]) != @[999.Gid]: quit 1

Nim Version

nim-devel HEAD from yesterday

Nim Compiler Version 2.1.9 [Linux: amd64]
Compiled at 2024-08-03
Copyright (c) 2006-2024 by Andreas Rumpf

active boot switches: -d:release -d:danger -d:nimUseLinenoise

Current Output

The example program fails under nim cpp --cc=gcc or nim cpp --cc=clang with any backend versions and with nim c --cc=gcc typeAliasSeq.nim under gcc-14 (without --passC=-Wno-error=incompatible-pointer-types - it works with that). The error message is roughly the same in all 3 failure cases:

CC: typeAliasSeq.nim
/u/cb/.cache/nim/typeAliasSeq_d/@mtypeAliasSeq.nim.c: In function 'grpToGid__type65lias83eq_u58':
/u/cb/.cache/nim/typeAliasSeq_d/@mtypeAliasSeq.nim.c:151:58: error: passing argument 1 of 'add__type65lias83eq_u30' from incompatible pointer type [-Wincompatible-pointer-types]
  151 |                                 add__type65lias83eq_u30((&result), ((unsigned int) (T5_)));
      |                                                         ~^~~~~~~~
      |                                                          |
      |                                                          tySequence__t9cg37mqWifZWh9b3z1fs0Og *
/u/cb/.cache/nim/typeAliasSeq_d/@mtypeAliasSeq.nim.c:67:93: note: expected 'tySequence__MOLaeFb9cv3vR6ovvXz0FCA *' but argument is of type 'tySequence__t9cg37mqWifZWh9b3z1fs0Og *'
   67 | N_LIB_PRIVATE N_NIMCALL(void, add__type65lias83eq_u30)(tySequence__MOLaeFb9cv3vR6ovvXz0FCA* x_p0, unsigned int y_p1);
      |                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~

Expected Output

Should compile and run without errors. It does so with nim c --cc=clang, or with early gcc versions and --cc=gcc, but does NOT with nim cpp -cc=clang or later gcc versions.

Possible Solution

Commenting out the Uid type and its two procs makes the problem go away. This is admittedly more of a "hint" to the solution and relates to my issue title than an actual solution.

Additional Information

The problem also goes away if cuint is changed to simply int (or int8 or etc. magic int types). So, AFAICT, the problem may only apply to importc types, but it may also be more broad like generic types, etc. Worth making a test that tries several things before concluding that it's solved.

c-blake commented 1 month ago

Possibly also of interest, I tried the same Uid/Gid test program from the linked issue on Nim-1.2, 1.4, 1.6 and it worked with both gcc & clang with either cpp or gcc-14 with every combination.

So, it seems this is a relatively recent problem and git bisecting Nim could probably isolate the changes that caused it.

ringabout commented 1 month ago

Possibly also of interest, I tried the same Uid/Gid test program from the linked issue on Nim-1.2, 1.4, 1.6 and it worked with both gcc & clang with either cpp or gcc-14 with every combination.

Probably not because it has been broken with old versions with ORC. It works well with refc.

c-blake commented 1 month ago

Aha - yes, I did not take the default gc/mm changing into account in my tests. Good catch!