[ARC] fixes #18645; C Compiler error when initializing {.global.} with a block (#19953)

* fixes #18645; C Compiler error when initializing {.global.} with a block:

* arguably cleaner solution

Co-authored-by: xflywind <43030857+xflywind@users.noreply.github.com>
Co-authored-by: Araq <rumpf_a@web.de>
This commit is contained in:
ringabout
2022-10-03 22:12:23 +08:00
committed by GitHub
parent 852a7c4919
commit 0f5ad49971
2 changed files with 35 additions and 12 deletions

View File

@@ -77,7 +77,7 @@ proc getTemp(c: var Con; s: var Scope; typ: PType; info: TLineInfo): PNode =
proc nestedScope(parent: var Scope; body: PNode): Scope =
Scope(vars: @[], locals: @[], wasMoved: @[], final: @[], body: body, needsTry: false, parent: addr(parent))
proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode
proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSingleUsedTemp}): PNode
proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope; isDecl = false): PNode
when false:
@@ -508,14 +508,14 @@ proc processScope(c: var Con; s: var Scope; ret: PNode): PNode =
if s.parent != nil: s.parent[].needsTry = s.parent[].needsTry or s.needsTry
template processScopeExpr(c: var Con; s: var Scope; ret: PNode, processCall: untyped): PNode =
template processScopeExpr(c: var Con; s: var Scope; ret: PNode, processCall: untyped, tmpFlags: TSymFlags): PNode =
assert not ret.typ.isEmptyType
var result = newNodeIT(nkStmtListExpr, ret.info, ret.typ)
# There is a possibility to do this check: s.wasMoved.len > 0 or s.final.len > 0
# later and use it to eliminate the temporary when theres no need for it, but its
# tricky because you would have to intercept moveOrCopy at a certain point
let tmp = c.getTemp(s.parent[], ret.typ, ret.info)
tmp.sym.flags.incl sfSingleUsedTemp
tmp.sym.flags = tmpFlags
let cpy = if hasDestructor(c, ret.typ):
s.parent[].final.add c.genDestroy(tmp)
moveOrCopy(tmp, ret, c, s, isDecl = true)
@@ -542,7 +542,8 @@ template processScopeExpr(c: var Con; s: var Scope; ret: PNode, processCall: unt
result
template handleNestedTempl(n, processCall: untyped, willProduceStmt = false) =
template handleNestedTempl(n, processCall: untyped, willProduceStmt = false,
tmpFlags = {sfSingleUsedTemp}) =
template maybeVoid(child, s): untyped =
if isEmptyType(child.typ): p(child, c, s, normal)
else: processCall(child, s)
@@ -570,7 +571,7 @@ template handleNestedTempl(n, processCall: untyped, willProduceStmt = false) =
branch[^1] = if it[^1].typ.isEmptyType or willProduceStmt:
processScope(c, ofScope, maybeVoid(it[^1], ofScope))
else:
processScopeExpr(c, ofScope, it[^1], processCall)
processScopeExpr(c, ofScope, it[^1], processCall, tmpFlags)
result.add branch
of nkWhileStmt:
@@ -603,7 +604,7 @@ template handleNestedTempl(n, processCall: untyped, willProduceStmt = false) =
result.add if n[1].typ.isEmptyType or willProduceStmt:
processScope(c, bodyScope, processCall(n[1], bodyScope))
else:
processScopeExpr(c, bodyScope, n[1], processCall)
processScopeExpr(c, bodyScope, n[1], processCall, tmpFlags)
of nkIfStmt, nkIfExpr:
result = copyNode(n)
@@ -618,7 +619,7 @@ template handleNestedTempl(n, processCall: untyped, willProduceStmt = false) =
branch[^1] = if it[^1].typ.isEmptyType or willProduceStmt:
processScope(c, branchScope, maybeVoid(it[^1], branchScope))
else:
processScopeExpr(c, branchScope, it[^1], processCall)
processScopeExpr(c, branchScope, it[^1], processCall, tmpFlags)
result.add branch
of nkTryStmt:
@@ -627,7 +628,7 @@ template handleNestedTempl(n, processCall: untyped, willProduceStmt = false) =
result.add if n[0].typ.isEmptyType or willProduceStmt:
processScope(c, tryScope, maybeVoid(n[0], tryScope))
else:
processScopeExpr(c, tryScope, n[0], maybeVoid)
processScopeExpr(c, tryScope, n[0], maybeVoid, tmpFlags)
for i in 1..<n.len:
let it = n[i]
@@ -637,7 +638,7 @@ template handleNestedTempl(n, processCall: untyped, willProduceStmt = false) =
processScope(c, branchScope, if it.kind == nkFinally: p(it[^1], c, branchScope, normal)
else: maybeVoid(it[^1], branchScope))
else:
processScopeExpr(c, branchScope, it[^1], processCall)
processScopeExpr(c, branchScope, it[^1], processCall, tmpFlags)
result.add branch
of nkWhen: # This should be a "when nimvm" node.
@@ -670,11 +671,11 @@ proc pRaiseStmt(n: PNode, c: var Con; s: var Scope): PNode =
result.add copyNode(n[0])
s.needsTry = true
proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSingleUsedTemp}): PNode =
if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt,
nkIfExpr, nkCaseStmt, nkWhen, nkWhileStmt, nkParForStmt, nkTryStmt}:
template process(child, s): untyped = p(child, c, s, mode)
handleNestedTempl(n, process)
handleNestedTempl(n, process, tmpFlags = tmpFlags)
elif mode == sinkArg:
if n.containsConstSeq:
# const sequences are not mutable and so we need to pass a copy to the
@@ -825,7 +826,11 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
var itCopy = copyNode(it)
for j in 0..<it.len-1:
itCopy.add it[j]
itCopy.add p(it[^1], c, s, normal)
var flags = {sfSingleUsedTemp}
if it.kind == nkIdentDefs and it.len == 3 and it[0].kind == nkSym and
sfGlobal in it[0].sym.flags:
flags.incl sfGlobal
itCopy.add p(it[^1], c, s, normal, tmpFlags = flags)
v.add itCopy
result.add v
of nkAsgn, nkFastAsgn:

18
tests/arc/t18645.nim Normal file
View File

@@ -0,0 +1,18 @@
discard """
matrix: "--gc:arc; --gc:refc"
output: '''
1
2
3
'''
"""
proc bitTypeIdUnion() =
var bitId {.global.} = block:
0
inc bitId
echo bitId
bitTypeIdUnion()
bitTypeIdUnion()
bitTypeIdUnion()