Skip to content

Commit

Permalink
cgen: fix regression with .nodecl consts (#785)
Browse files Browse the repository at this point in the history
## Summary

Fix a regression where the C code generator ignored the `.nodecl`
pragma for constants.

## Details

Apart from the fix, the single-use `genConstSetup` is inlined into
`useConst`. Since the loc for constants is setup in `genConstDefinition`
(which is always called before `useConst`), the `fillLoc` call is not
added to `useConst` (this is also a step towards `fillLoc` only being
used in procedures responsible for definitions).

In addition, a test for the current behaviour of imported `.nodecl`
  • Loading branch information
zerbina authored Jul 7, 2023
1 parent c9fb1c7 commit 9545f36
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
20 changes: 8 additions & 12 deletions compiler/backend/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2136,14 +2136,9 @@ proc fillConstLoc(m: BModule, sym: PSym) =
if sym.loc.k == locNone:
fillLoc(sym.loc, locData, sym.ast, mangleName(m, sym), OnStatic)

proc genConstSetup(m: BModule; sym: PSym): bool =
useHeader(m, sym)
fillConstLoc(m, sym)

result = lfNoDecl notin sym.loc.flags

proc useConst*(m: BModule; sym: PSym) =
if not genConstSetup(m, sym):
useHeader(m, sym)
if lfNoDecl in sym.loc.flags:
return

assert(sym.loc.r != "", $sym.name.s & $sym.itemId)
Expand All @@ -2156,11 +2151,12 @@ proc useConst*(m: BModule; sym: PSym) =
m.s[cfsData].add(headerDecl)

proc genConstDefinition*(q: BModule; sym: PSym) =
let p = newProc(nil, q)
fillConstLoc(q, sym)
q.s[cfsData].addf("N_LIB_PRIVATE NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(q, sym.typ), sym.loc.r,
genBracedInit(p, sym.ast, isConst = true, sym.typ)])
fillConstLoc(q, sym) # all consts need a valid loc
if lfNoDecl notin sym.loc.flags:
let p = newProc(nil, q)
q.s[cfsData].addf("N_LIB_PRIVATE NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(q, sym.typ), sym.loc.r,
genBracedInit(p, sym.ast, isConst = true, sym.typ)])

proc expr(p: BProc, n: PNode, d: var TLoc) =
when defined(nimCompilerStacktraceHints):
Expand Down
23 changes: 23 additions & 0 deletions tests/lang/s05_pragmas/s01_interop/t04_imported_constants.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
discard """
targets: "c js"
description: '''
A |NimSkull| constant can act as an alias for an external, constant
entity
'''
"""

type Obj = object # something complex that isn't inlined
val: int

const
constA {.exportc.} = Obj(val: 2)
constB {.importc: "constA", nodecl.} = Obj(val: 1)

static:
# in a compile-time context, the constant represents the value as is
# specified by the constant's initializer expression
doAssert constB == Obj(val: 1)

# in a run-time context, the constant acts as an alias for the imported
# entity
doAssert constB == Obj(val: 2)

0 comments on commit 9545f36

Please sign in to comment.