Skip to content
Permalink
Browse files

[bugfix] fixes #11524

(cherry picked from commit 79c721d)
  • Loading branch information...
Araq authored and narimiran committed Jun 21, 2019
1 parent 4d18ee4 commit 433dfaf288bf1c505086ecbf6a53526c050754e4
Showing with 40 additions and 5 deletions.
  1. +29 −2 compiler/injectdestructors.nim
  2. +10 −1 tests/destructor/tgcdestructors.nim
  3. +1 −2 tests/destructor/tnewruntime_strutils.nim
@@ -450,6 +450,25 @@ proc passCopyToSink(n: PNode; c: var Con): PNode =
result.add newTree(nkAsgn, tmp, p(n, c))
result.add tmp

proc isDangerousSeq(t: PType): bool {.inline.} =
let t = t.skipTypes(abstractInst)
result = t.kind == tySequence and tfHasOwned notin t.sons[0].flags

proc containsConstSeq(n: PNode): bool =
if n.kind == nkBracket and n.len > 0 and n.typ != nil and isDangerousSeq(n.typ):
return true
result = false
case n.kind
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
result = containsConstSeq(n[1])
of nkObjConstr, nkClosure:
for i in 1 ..< n.len:
if containsConstSeq(n[i]): return true
of nkCurly, nkBracket, nkPar, nkTupleConstr:
for i in 0 ..< n.len:
if containsConstSeq(n[i]): return true
else: discard

proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
template pArgIfTyped(argPart: PNode): PNode =
# typ is nil if we are in if/case expr branch with noreturn
@@ -466,7 +485,12 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
result.add arg[0]
for i in 1..<arg.len:
result.add pArg(arg[i], c, i < L and isSinkTypeForParam(parameters[i]))
elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkBracket, nkCharLit..nkTripleStrLit}:
elif arg.containsConstSeq:
# const sequences are not mutable and so we need to pass a copy to the
# sink parameter (bug #11524). Note that the string implemenation is
# different and can deal with 'const string sunk into var'.
result = passCopyToSink(arg, c)
elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkCharLit..nkTripleStrLit}:
discard "object construction to sink parameter: nothing to do"
result = arg
elif arg.kind == nkSym and isSinkParam(arg.sym):
@@ -595,7 +619,10 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
result.add branch
of nkBracket:
# array constructor
result = genSink(c, dest.typ, dest, ri)
if ri.len > 0 and isDangerousSeq(ri.typ):
result = genCopy(c, dest.typ, dest, ri)
else:
result = genSink(c, dest.typ, dest, ri)
let ri2 = copyTree(ri)
for i in 0..<ri.len:
# everything that is passed to an array constructor is consumed,
@@ -6,7 +6,8 @@ ha
@["arg", "asdfklasdfkl", "asdkfj", "dfasj", "klfjl"]
@[1, 2, 3]
@["red", "yellow", "orange", "rtrt1", "pink"]
30 30'''
a: @[4, 2, 3]
35 35'''
"""

import allocators
@@ -169,6 +170,14 @@ proc testWarm =

testWarm()

proc mutConstSeq() =
# bug #11524
var a = @[1,2,3]
a[0] = 4
echo "a: ", a

mutConstSeq()

#echo s
let (a, d) = allocCounters()
discard cprintf("%ld %ld\n", a, d)
@@ -1,6 +1,6 @@
discard """
cmd: '''nim c --newruntime $file'''
output: '''442 442'''
output: '''443 443'''
"""

import strutils, os
@@ -10,7 +10,6 @@ import system / ansi_c

# bug #11004
proc retTuple(): (seq[int], int) =
# XXX this doesn't allocate yet but probably it should
return (@[1], 1)

proc nonStaticTests =

0 comments on commit 433dfaf

Please sign in to comment.
You can’t perform that action at this time.