mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-08 14:03:23 +00:00
fixes #24940
fixes #17552
Collects `{.global.}` (i.e. if it was changed into a hook call: `=copy`,
`=sink`) in `injectDestructorCalls` and generates it in the init
sections in cgen
(cherry picked from commit 3c0446b082)
This commit is contained in:
@@ -2183,6 +2183,9 @@ proc genTopLevelStmt*(m: BModule; n: PNode) =
|
||||
else:
|
||||
genProcBody(m.initProc, transformedN)
|
||||
|
||||
for g in m.g.graph.procGlobals:
|
||||
genStmts(m.preInitProc, g)
|
||||
|
||||
proc shouldRecompile(m: BModule; code: Rope, cfile: Cfile): bool =
|
||||
if optForceFullMake notin m.config.globalOptions:
|
||||
if not moduleHasChanged(m.g.graph, m.module):
|
||||
|
||||
@@ -936,6 +936,9 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
|
||||
of nkVarSection, nkLetSection:
|
||||
# transform; var x = y to var x; x op y where op is a move or copy
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
|
||||
let isInProc = c.owner.kind in {skProc, skFunc, skMethod, skIterator, skConverter}
|
||||
|
||||
for it in n:
|
||||
var ri = it[^1]
|
||||
if it.kind == nkVarTuple and hasDestructor(c, ri.typ):
|
||||
@@ -951,7 +954,15 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
|
||||
s.locals.add v.sym
|
||||
pVarTopLevel(v, c, s, result)
|
||||
if ri.kind != nkEmpty:
|
||||
result.add moveOrCopy(v, ri, c, s, if v.kind == nkSym: {IsDecl} else: {})
|
||||
let isGlobalPragma = v.kind == nkSym and
|
||||
{sfPure, sfGlobal} <= v.sym.flags and
|
||||
isInProc
|
||||
|
||||
let value = moveOrCopy(v, ri, c, s, if v.kind == nkSym: {IsDecl} else: {})
|
||||
if isGlobalPragma:
|
||||
c.graph.procGlobals.add value
|
||||
else:
|
||||
result.add value
|
||||
elif ri.kind == nkEmpty and c.inLoop > 0:
|
||||
let skipInit = v.kind == nkDotExpr and # Closure var
|
||||
sfNoInit in v[1].sym.flags
|
||||
|
||||
@@ -136,6 +136,8 @@ type
|
||||
|
||||
cachedFiles*: StringTableRef
|
||||
|
||||
procGlobals*: seq[PNode]
|
||||
|
||||
TPassContext* = object of RootObj # the pass's context
|
||||
idgen*: IdGenerator
|
||||
PPassContext* = ref TPassContext
|
||||
|
||||
30
tests/global/tglobal3.nim
Normal file
30
tests/global/tglobal3.nim
Normal file
@@ -0,0 +1,30 @@
|
||||
discard """
|
||||
matrix: "--mm:refc; --mm:orc"
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
block: # bug #17552
|
||||
proc main: string =
|
||||
var tc {.global.} = "hi"
|
||||
tc &= "hi"
|
||||
result = tc
|
||||
|
||||
doAssert main() == "hihi"
|
||||
doAssert main() == "hihihi"
|
||||
doAssert main() == "hihihihi"
|
||||
|
||||
# bug #24940
|
||||
var v: int
|
||||
|
||||
proc ccc(): ref int =
|
||||
let tmp = new int
|
||||
v += 1
|
||||
tmp[] = v
|
||||
tmp
|
||||
|
||||
proc f(v: static string): int =
|
||||
let xxx {.global.} = ccc()
|
||||
xxx[]
|
||||
|
||||
doAssert f("1") == 1
|
||||
doAssert f("1") == 1
|
||||
Reference in New Issue
Block a user