fixes #19457 seqs are not properly updated in loop with ARC/ORC (#19922)

* test CI

* fixes #19457

* add comments

Co-authored-by: sandytypical <43030857+xflywind@users.noreply.github.com>
This commit is contained in:
ringabout 2022-09-28 19:12:08 +08:00 • committed by GitHub
commit fe8feb46c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 15 deletions

View file

@ -767,6 +767,11 @@ proc traverse(c: var Partitions; n: PNode) =
# mutate(graph) # mutate(graph)
# connect(graph, cursorVar) # connect(graph, cursorVar)
for child in n: traverse(c, child) for child in n: traverse(c, child)
if n.kind == nkWhileStmt:
traverse(c, n[0])
# variables in while condition has longer alive time than local variables
# in the while loop body
else: else:
for child in n: traverse(c, child) for child in n: traverse(c, child)
@ -854,6 +859,11 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
inc c.inLoop inc c.inLoop
for child in n: computeLiveRanges(c, child) for child in n: computeLiveRanges(c, child)
dec c.inLoop dec c.inLoop
if n.kind == nkWhileStmt:
computeLiveRanges(c, n[0])
# variables in while condition has longer alive time than local variables
# in the while loop body
of nkElifBranch, nkElifExpr, nkElse, nkOfBranch: of nkElifBranch, nkElifExpr, nkElse, nkOfBranch:
inc c.inConditional inc c.inConditional
for child in n: computeLiveRanges(c, child) for child in n: computeLiveRanges(c, child)

16
tests/arc/t19457.nim Normal file
View file

@ -0,0 +1,16 @@
discard """
matrix: "--gc:refc; --gc:arc"
"""
# bug #19457
proc gcd(x, y: seq[int]): seq[int] =
var
a = x
b = y
while b[0] > 0:
let c = @[a[0] mod b[0]]
a = b
b = c
return a
doAssert gcd(@[1], @[2]) == @[1]

View file

@ -5,21 +5,28 @@ discard """
var var
it_cursor it_cursor
jt_cursor jt
it_cursor = root try:
block :tmp: it_cursor = root
while ( block :tmp:
not (it_cursor == nil)): while (
echo [it_cursor.s] not (it_cursor == nil)):
it_cursor = it_cursor.ri echo [it_cursor.s]
jt_cursor = root it_cursor = it_cursor.ri
block :tmp_1: `=copy`(jt, root)
while ( block :tmp_1:
not (jt_cursor == nil)): while (
var ri_1_cursor not (jt == nil)):
ri_1_cursor = jt_cursor.ri var ri_1
echo [jt_cursor.s] try:
jt_cursor = ri_1_cursor `=copy`(ri_1, jt.ri)
echo [jt.s]
`=sink`(jt, ri_1)
wasMoved(ri_1)
finally:
`=destroy`(ri_1)
finally:
`=destroy`(jt)
-- end of expandArc ------------------------''' -- end of expandArc ------------------------'''
""" """