From 73aeac81d1616494eef5c0fab2dae72f747d97e5 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:54:00 +0800 Subject: [PATCH] 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 --- compiler/optimizer.nim | 8 ++++++++ tests/arc/t24806.nim | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/arc/t24806.nim diff --git a/compiler/optimizer.nim b/compiler/optimizer.nim index 34e8ec80f4..bf188334b1 100644 --- a/compiler/optimizer.nim +++ b/compiler/optimizer.nim @@ -28,11 +28,14 @@ type hasReturn, hasBreak: bool label: PSym # can be nil parent: ptr BasicBlock + symToDel: seq[PNode] Con = object somethingTodo: bool inFinally: int +proc invalidateWasMoved(c: var BasicBlock; x: PNode) + proc nestedBlock(parent: var BasicBlock; kind: TNodeKind): BasicBlock = BasicBlock(wasMovedLocs: @[], kind: kind, hasReturn: false, hasBreak: false, label: nil, parent: addr(parent)) @@ -62,6 +65,10 @@ proc mergeBasicBlockInfo(parent: var BasicBlock; this: BasicBlock) {.inline.} = if this.hasReturn: parent.wasMovedLocs.setLen 0 parent.hasReturn = true + elif this.symToDel.len > 0: + parent.symToDel = this.symToDel + for i in this.symToDel: + invalidateWasMoved(parent, i) proc wasMovedTarget(matches: var IntSet; branch: seq[PNode]; moveTarget: PNode): bool = result = false @@ -149,6 +156,7 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) = # any usage of the location before destruction implies we # cannot elide the 'wasMoved(x)': b.invalidateWasMoved n + b.symToDel.add n of nkNone..pred(nkSym), succ(nkSym)..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo, diff --git a/tests/arc/t24806.nim b/tests/arc/t24806.nim new file mode 100644 index 0000000000..4af0f5c1a3 --- /dev/null +++ b/tests/arc/t24806.nim @@ -0,0 +1,39 @@ +discard """ + matrix: "-d:useMalloc;" +""" + +type + GlobFilter* = object + incl*: bool + glob*: string + + GlobState* = object + one: int + two: int + +proc aa() = + let filters = @[GlobFilter(incl: true, glob: "**")] + var wbg = newSeqOfCap[GlobState](1) + wbg.add GlobState() + var + dirc = @[wbg] + while true: + wbg = dirc[^1] + dirc.add wbg + break + +var handlerLocs = newSeq[string]() +handlerLocs.add "sammich" +aa() +aa() + +block: # bug #24806 + proc aa() = + var + a = @[0] + b = @[a] + block: + a = b[0] + b.add a + + aa()