mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-05 04:27:44 +00:00
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user