Skip to content

Commit 73aeac8

Browse files
authored
fixes #24806; don't elide wasMoved when syms are used in blocks (#24831)
fixes #24806 Blocks don't merge symbols that are used before destruction to the parent scope, which causes `wasMoved; destroy` to elide incorrectly
1 parent 5bcd9a3 commit 73aeac8

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

compiler/optimizer.nim

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ type
2828
hasReturn, hasBreak: bool
2929
label: PSym # can be nil
3030
parent: ptr BasicBlock
31+
symToDel: seq[PNode]
3132

3233
Con = object
3334
somethingTodo: bool
3435
inFinally: int
3536

37+
proc invalidateWasMoved(c: var BasicBlock; x: PNode)
38+
3639
proc nestedBlock(parent: var BasicBlock; kind: TNodeKind): BasicBlock =
3740
BasicBlock(wasMovedLocs: @[], kind: kind, hasReturn: false, hasBreak: false,
3841
label: nil, parent: addr(parent))
@@ -62,6 +65,10 @@ proc mergeBasicBlockInfo(parent: var BasicBlock; this: BasicBlock) {.inline.} =
6265
if this.hasReturn:
6366
parent.wasMovedLocs.setLen 0
6467
parent.hasReturn = true
68+
elif this.symToDel.len > 0:
69+
parent.symToDel = this.symToDel
70+
for i in this.symToDel:
71+
invalidateWasMoved(parent, i)
6572

6673
proc wasMovedTarget(matches: var IntSet; branch: seq[PNode]; moveTarget: PNode): bool =
6774
result = false
@@ -149,6 +156,7 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) =
149156
# any usage of the location before destruction implies we
150157
# cannot elide the 'wasMoved(x)':
151158
b.invalidateWasMoved n
159+
b.symToDel.add n
152160

153161
of nkNone..pred(nkSym), succ(nkSym)..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef,
154162
nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo,

tests/arc/t24806.nim

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
discard """
2+
matrix: "-d:useMalloc;"
3+
"""
4+
5+
type
6+
GlobFilter* = object
7+
incl*: bool
8+
glob*: string
9+
10+
GlobState* = object
11+
one: int
12+
two: int
13+
14+
proc aa() =
15+
let filters = @[GlobFilter(incl: true, glob: "**")]
16+
var wbg = newSeqOfCap[GlobState](1)
17+
wbg.add GlobState()
18+
var
19+
dirc = @[wbg]
20+
while true:
21+
wbg = dirc[^1]
22+
dirc.add wbg
23+
break
24+
25+
var handlerLocs = newSeq[string]()
26+
handlerLocs.add "sammich"
27+
aa()
28+
aa()
29+
30+
block: # bug #24806
31+
proc aa() =
32+
var
33+
a = @[0]
34+
b = @[a]
35+
block:
36+
a = b[0]
37+
b.add a
38+
39+
aa()

0 commit comments

Comments
 (0)