Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cgen generates the same struct twice when importing a distinct object #1417

Closed
starsiderfox opened this issue Aug 14, 2024 · 1 comment · Fixed by #1418
Closed

cgen generates the same struct twice when importing a distinct object #1417

starsiderfox opened this issue Aug 14, 2024 · 1 comment · Fixed by #1418
Assignees
Labels
bug Something isn't working compiler/backend Related to backend system of the compiler

Comments

@starsiderfox
Copy link
Contributor

Specification

When using importc and nodecl for an object that is just a distinct of another object, the compiler erroneously writes the same struct twice. When I edit the .c file to remove the duplicate, it works properly.

Example

Compile with --passL:-latomic

type int128* = object
        hi*{.align:16.}, lo*: uint64
type cint128 {.importc: "__int128",nodecl.} = distinct int128

let x = int128(hi: 123'u64, lo: 321'u64)
let y = cast[cint128](x)
echo cast[int128](y)

Actual Output

/home/user/.cache/nimskull/dupli_d/@mdupli.nim.c:42:8: error: redefinition of 'struct _G6int128_M5dupli'
   42 | struct _G6int128_M5dupli {
      |        ^~~~~~~~~~~~~~~~~
/home/user/.cache/nimskull/dupli_d/@mdupli.nim.c:38:8: note: originally defined here
   38 | struct _G6int128_M5dupli {
      |        ^~~~~~~~~~~~~~~~~

execution of an external program 'gcc -c  -w -fmax-errors=3   -I/home/user/nimskull/lib -I/tmp -o /home/user/.cache/nimskull/dupli_d/@mdupli.nim.c.o /home/user/.cache/nimskull/dupli_d/@mdupli.nim.c' failed with exit code '1'

Expected Output

(hi: 123, lo: 321)
@starsiderfox starsiderfox added the bug Something isn't working label Aug 14, 2024
@zerbina zerbina added the compiler/backend Related to backend system of the compiler label Aug 14, 2024
@zerbina
Copy link
Collaborator

zerbina commented Aug 14, 2024

A regression introduced by #1382. The way imported types are handled here:

let base = typeSymToMir(env):
if t.kind in Skip:
t.lastSon.skipIrrelevant()
else:
t

leads to duplicate type mappings being introduced for distinct or alias types.

@zerbina zerbina self-assigned this Aug 14, 2024
github-merge-queue bot pushed a commit that referenced this issue Aug 15, 2024
## Summary

Marking a `distinct T` type as imported resulted in multiple C
definitions for `T`, if `T` is a non-numeric, non-pointer type. This is
now fixed.

Fixes #1417.

## Details

When translating imported types, `mirtypes` always created a new type
symbol for the imported type's underlying type. For `tyAlias` and
`tyDistinct` types (or any other type kind in the `Skip` set), this
resulted in a duplicate of the underlying type symbol being created.
Since MIR types are identified by ID, both look separate to `cgen`, and
thus a C definition is emitted for each.

`handleImportedTypes` now goes through the caching mechanism for the
underlying type if its not the type marked with `.importc`, fixing the
issue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler/backend Related to backend system of the compiler
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants