Skip to content

Commit 3f6df5c

Browse files
authored
fixes #12899 (#12921)
* fixes #12899 * fixes regression: destroy global variables in reverse declaration order, closureleak test relies on it
1 parent f9f55a2 commit 3f6df5c

File tree

5 files changed

+45
-15
lines changed

5 files changed

+45
-15
lines changed

compiler/ccgexprs.nim

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,13 +2031,15 @@ proc genDestroy(p: BProc; n: PNode) =
20312031
var a: TLoc
20322032
initLocExpr(p, arg, a)
20332033
linefmt(p, cpsStmts, "if ($1.p && $1.p->allocator) {$n" &
2034-
" $1.p->allocator->dealloc($1.p->allocator, $1.p, $1.p->cap + 1 + sizeof(NI) + sizeof(void*)); }$n",
2034+
" $1.p->allocator->dealloc($1.p->allocator, $1.p, $1.p->cap + 1 + sizeof(NI) + sizeof(void*));$n" &
2035+
" $1.p = NIM_NIL; }$n",
20352036
[rdLoc(a)])
20362037
of tySequence:
20372038
var a: TLoc
20382039
initLocExpr(p, arg, a)
20392040
linefmt(p, cpsStmts, "if ($1.p && $1.p->allocator) {$n" &
2040-
" $1.p->allocator->dealloc($1.p->allocator, $1.p, ($1.p->cap * sizeof($2)) + sizeof(NI) + sizeof(void*)); }$n",
2041+
" $1.p->allocator->dealloc($1.p->allocator, $1.p, ($1.p->cap * sizeof($2)) + sizeof(NI) + sizeof(void*));$n" &
2042+
" $1.p = NIM_NIL; }$n",
20412043
[rdLoc(a), getTypeDesc(p.module, t.lastSon)])
20422044
else: discard "nothing to do"
20432045
else:

compiler/cgen.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,8 +1981,8 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
19811981
if b == nil: return
19821982
var m = BModule(b)
19831983
if sfMainModule in m.module.flags:
1984-
for destructorCall in graph.globalDestructors:
1985-
n.add destructorCall
1984+
for i in countdown(high(graph.globalDestructors), 0):
1985+
n.add graph.globalDestructors[i]
19861986
if passes.skipCodegen(m.config, n): return
19871987
if moduleHasChanged(graph, m.module):
19881988
# if the module is cached, we don't regenerate the main proc

compiler/liftdestructors.nim

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
429429
body.add genIf(c, cond, actions)
430430
body.add newAsgnStmt(x, y)
431431
of attachedDestructor:
432-
when false:
433-
# XXX investigate if this is necessary:
434-
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
432+
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
435433
body.add genIf(c, cond, actions)
436434
of attachedDeepCopy: assert(false, "cannot happen")
437435
of attachedTrace:
@@ -480,9 +478,7 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
480478
body.add genIf(c, cond, actions)
481479
body.add newAsgnStmt(x, y)
482480
of attachedDestructor:
483-
when false:
484-
# XXX investigate if this is necessary:
485-
actions.add newAsgnStmt(xenv, newNodeIT(nkNilLit, body.info, xenv.typ))
481+
actions.add newAsgnStmt(xenv, newNodeIT(nkNilLit, body.info, xenv.typ))
486482
body.add genIf(c, cond, actions)
487483
of attachedDeepCopy: assert(false, "cannot happen")
488484
of attachedTrace:
@@ -510,7 +506,10 @@ proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
510506
of attachedDestructor:
511507
# it's better to prepend the destruction of weak refs in order to
512508
# prevent wrong "dangling refs exist" problems:
513-
let des = genIf(c, x, callCodegenProc(c.g, "nimDecWeakRef", c.info, x))
509+
var actions = newNodeI(nkStmtList, c.info)
510+
actions.add callCodegenProc(c.g, "nimDecWeakRef", c.info, x)
511+
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
512+
let des = genIf(c, x, actions)
514513
if body.len == 0:
515514
body.add des
516515
else:
@@ -537,6 +536,7 @@ proc ownedRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
537536
body.add genIf(c, x, actions)
538537
body.add newAsgnStmt(x, y)
539538
of attachedDestructor:
539+
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
540540
body.add genIf(c, x, actions)
541541
of attachedDeepCopy: assert(false, "cannot happen")
542542
of attachedTrace, attachedDispose: discard
@@ -567,7 +567,10 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
567567
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
568568
body.add newAsgnStmt(x, y)
569569
of attachedDestructor:
570-
let des = genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
570+
var actions = newNodeI(nkStmtList, c.info)
571+
actions.add callCodegenProc(c.g, "nimDecWeakRef", c.info, xx)
572+
actions.add newAsgnStmt(xx, newNodeIT(nkNilLit, body.info, xx.typ))
573+
let des = genIf(c, xx, actions)
571574
if body.len == 0:
572575
body.add des
573576
else:
@@ -586,6 +589,7 @@ proc ownedClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
586589
body.add genIf(c, xx, actions)
587590
body.add newAsgnStmt(x, y)
588591
of attachedDestructor:
592+
actions.add newAsgnStmt(xx, newNodeIT(nkNilLit, body.info, xx.typ))
589593
body.add genIf(c, xx, actions)
590594
of attachedDeepCopy: assert(false, "cannot happen")
591595
of attachedTrace, attachedDispose: discard

tests/destructor/tnewruntime_strutils.nim

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
discard """
22
valgrind: true
33
cmd: '''nim c --newruntime -d:useMalloc $file'''
4-
output: '''422 422'''
4+
output: '''
5+
@[(input: @["KXSC", "BGMC"]), (input: @["PXFX"]), (input: @["WXRQ", "ZSCZD"])]
6+
461 461'''
57
"""
68

79
import strutils, os, std / wordwrap
@@ -13,6 +15,28 @@ import system / ansi_c
1315
proc retTuple(): (seq[int], int) =
1416
return (@[1], 1)
1517

18+
# bug #12899
19+
20+
import sequtils, strmisc
21+
22+
const input = ["KXSC, BGMC => 7 PTHL", "PXFX => LBZJ", "WXRQ, ZSCZD => HLQM"]
23+
24+
type
25+
Reaction = object
26+
input: seq[string]
27+
28+
proc bug12899 =
29+
var reactions: seq[Reaction] = @[]
30+
for l in input:
31+
let x = l.partition(" => ")
32+
reactions.add Reaction(input: @(x[0].split(", ")))
33+
34+
let x = $reactions
35+
echo x
36+
37+
bug12899()
38+
39+
1640
proc nonStaticTests =
1741
doAssert formatBiggestFloat(1234.567, ffDecimal, -1) == "1234.567000"
1842
doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235" # bugs 8242, 12586

tests/gc/closureleak.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ discard """
66
type
77
TFoo* = object
88
id: int
9-
fn: proc(){.closure.}
9+
fn: proc() {.closure.}
1010
var foo_counter = 0
1111
var alive_foos = newseq[int](0)
1212

@@ -31,7 +31,7 @@ proc newFoo*(): ref TFoo =
3131
inc foo_counter
3232

3333
for i in 0 ..< 10:
34-
discard newFoo()
34+
discard newFoo()
3535

3636
for i in 0 ..< 10:
3737
let f = newFoo()

0 commit comments

Comments
 (0)