Skip to content

Commit 4998aff

Browse files
authored
fixes #25925 (#25926)
1 parent 4e1dd0b commit 4998aff

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

compiler/cgen.nim

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,8 +838,12 @@ proc assignGlobalVar(p: BProc, n: PNode; value: Rope) =
838838
else:
839839
initializer = value
840840
genGlobalVarDecl(p.module.s[cfsVars], p, n, td, initializer = initializer)
841-
if p.withinLoop > 0 and value == "":
841+
if p.withinLoop > 0 and value == "" and
842+
s.loc.t.skipTypes(abstractInst).kind notin {tyVar, tyLent}:
842843
# fixes tests/run/tzeroarray:
844+
# Don't reset borrowed references (var/lent): the pointer itself is still
845+
# uninitialized here, so resetLoc would dereference garbage. Such variables
846+
# (e.g. the loop var of `mitems`) are always assigned before use anyway.
843847
backendEnsureMutable s
844848
resetLoc(p, s.locImpl)
845849

tests/arc/tmitems_loopvar.nim

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
discard """
2+
output: '''a
3+
b
4+
c
5+
a
6+
b
7+
c'''
8+
"""
9+
10+
# A `var T` loop variable (here from `mitems`) declared inside an enclosing
11+
# loop must not be reset by dereferencing: at module scope it is emitted as a
12+
# global, and the in-loop reset path used `resetLoc`, which dereferenced the
13+
# still-uninitialized borrowed pointer and crashed with a SIGSEGV.
14+
15+
for p in @["abc", "123"]:
16+
var testA = @["a", "b", "c"]
17+
for l in testA.mitems:
18+
echo(l)
19+
20+
# also exercise actual mutation through the borrowed reference
21+
block:
22+
var ok = true
23+
for p in @["x", "y"]:
24+
var s = @[1, 2, 3]
25+
for l in s.mitems:
26+
l += 10
27+
if s != @[11, 12, 13]: ok = false
28+
doAssert ok

0 commit comments

Comments
 (0)