Skip to content

Commit

Permalink
fix #3505 wrong var {.global.} initialization, asign variable to it (#…
Browse files Browse the repository at this point in the history
…20812)

* fix #3505 wrong var {.global.} initialization, asign variable to it

* fix #5132 as well

* follow suggestions

* handle all call kinds

* Update tests/global/t3505.nim

* Update compiler/semstmts.nim

* Update compiler/semstmts.nim

* Update compiler/semstmts.nim

* follow suggestion

* Update compiler/semstmts.nim

Co-authored-by: Andreas Rumpf <[email protected]>
(cherry picked from commit 1410243)
  • Loading branch information
bung87 authored and narimiran committed Apr 25, 2023
1 parent ed2c2ee commit 21d9120
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
22 changes: 21 additions & 1 deletion compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const
errRecursiveDependencyX = "recursive dependency: '$1'"
errRecursiveDependencyIteratorX = "recursion is not supported in iterators: '$1'"
errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1"
errCannotAssignToGlobal = "cannot assign local to global variable"

proc semDiscard(c: PContext, n: PNode): PNode =
result = n
Expand Down Expand Up @@ -516,6 +517,24 @@ proc errorSymChoiceUseQualifier(c: PContext; n: PNode) =
inc i
localError(c.config, n.info, errGenerated, err)

template isLocalVarSym(n: PNode): bool =
n.kind == nkSym and
n.sym.kind in {skVar, skLet} and not
({sfGlobal, sfPure} <= n.sym.flags or
sfCompileTime in n.sym.flags)

proc usesLocalVar(n: PNode): bool =
for z in 1 ..< n.len:
if n[z].isLocalVarSym:
return true
elif n[z].kind in nkCallKinds:
if usesLocalVar(n[z]):
return true

proc globalVarInitCheck(c: PContext, n: PNode) =
if n.isLocalVarSym or n.kind in nkCallKinds and usesLocalVar(n):
localError(c.config, n.info, errCannotAssignToGlobal)

proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if n.len == 1:
result = semLowerLetVarCustomPragma(c, n[0], n)
Expand Down Expand Up @@ -668,7 +687,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
vm.setupCompileTimeVar(c.module, c.idgen, c.graph, x)
if v.flags * {sfGlobal, sfThread} == {sfGlobal}:
message(c.config, v.info, hintGlobalVar)

if {sfGlobal, sfPure} <= v.flags:
globalVarInitCheck(c, def)
suggestSym(c.graph, v.info, v, c.graph.usageSym)

proc semConst(c: PContext, n: PNode): PNode =
Expand Down
33 changes: 33 additions & 0 deletions tests/global/t3505.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
discard """
cmd: "nim check $options --hints:off $file"
action: "reject"
nimout: '''
t3505.nim(22, 22) Error: cannot assign local to global variable
t3505.nim(31, 28) Error: cannot assign local to global variable
'''
"""






proc foo =
let a = 0
var b {.global.} = a
foo()

# issue #5132
proc initX(it: float): int = 8
proc initX2(it: int): int = it

proc main() =
var f: float
var x {.global.} = initX2(initX(f))

main()

0 comments on commit 21d9120

Please sign in to comment.