fixes #26015; Multiple definition error when using codegenDecl regression (#26018)

fixes #26015

Fixes imported global variables with codegenDecl being emitted as
definitions instead of extern declarations.

A variable’s codegenDecl format should customize its definition in the
owning module. Other modules referencing the variable must emit a normal
declaration:

```c
extern NI variable;
```

After the variable-declaration builder refactor, genVarPrototype passed
Extern visibility to addVar. However, the sfCodegenDecl branch returned
before applying that visibility. This caused importing modules to emit
another tentative definition, resulting in duplicate-symbol linker
errors.

The fix restores the previous distinction between the custom definition
and cross-module prototypes. It also adds C and C++ regression coverage
for both direct access and access through an inline procedure.

follows up https://github.com/nim-lang/Nim/pull/24423
This commit is contained in:
ringabout
2026-08-23 18:37:15 +08:00
committed by GitHub
parent 37223d2ea9
commit 2d1412a2ea
3 changed files with 27 additions and 4 deletions

View File

@@ -1854,10 +1854,16 @@ proc genVarPrototype(m: BModule, n: PNode) =
typ = ptrType(typ)
if lfDynamicLib in sym.loc.flags:
typ = ptrType(typ)
m.s[cfsVars].addVar(m, sym,
name = sym.loc.snippet,
typ = typ,
visibility = vis)
if sfCodegenDecl in sym.flags:
m.s[cfsVars].addDeclWithVisibility(vis):
m.s[cfsVars].addVar(m, sym,
name = sym.loc.snippet,
typ = typ)
else:
m.s[cfsVars].addVar(m, sym,
name = sym.loc.snippet,
typ = typ,
visibility = vis)
if m.hcrOn:
m.initProc.procSec(cpsLocals).add('\t')
m.initProc.procSec(cpsLocals).addAssignment(sym.loc.snippet,

View File

@@ -0,0 +1,4 @@
var codegenDeclGlobal* {.codegenDecl: "$# /* custom declaration */ $#".} = 123
proc readCodegenDeclGlobal*(): int {.inline.} =
codegenDeclGlobal

View File

@@ -0,0 +1,13 @@
discard """
output: '''
123
123
'''
ccodecheck: "'extern NI /* custom declaration */ codegenDeclGlobal'"
targets: "c cpp"
"""
import ./mcodegendeclglobal
echo codegenDeclGlobal
echo readCodegenDeclGlobal()