mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 14:00:35 +00:00
* 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 <rumpf_a@web.de>
This commit is contained in:
@@ -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
|
||||
@@ -590,6 +591,24 @@ proc msgSymChoiceUseQualifier(c: PContext; n: PNode; note = errGenerated) =
|
||||
inc i
|
||||
message(c.config, n.info, note, 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 =
|
||||
var b: PNode
|
||||
result = copyNode(n)
|
||||
@@ -740,7 +759,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 =
|
||||
|
||||
33
tests/global/t3505.nim
Normal file
33
tests/global/t3505.nim
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user