fixes #24175; Sink parameters not copied at compile time (#24178)

fixes #24175
This commit is contained in:
ringabout
2024-09-27 15:36:09 +08:00
committed by GitHub
parent 75b9d66582
commit d4027f25c4
2 changed files with 57 additions and 1 deletions

View File

@@ -53,6 +53,7 @@ type
gfNode # Affects how variables are loaded - always loads as rkNode
gfNodeAddr # Affects how variables are loaded - always loads as rkNodeAddr
gfIsParam # do not deepcopy parameters, they are immutable
gfIsSinkParam # deepcopy sink parameters
TGenFlags = set[TGenFlag]
proc debugInfo(c: PCtx; info: TLineInfo): string =
@@ -620,10 +621,17 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) =
let fntyp = skipTypes(n[0].typ, abstractInst)
for i in 0..<n.len:
var r: TRegister = x+i
c.gen(n[i], r, {gfIsParam})
if i >= fntyp.signatureLen:
c.gen(n[i], r, {gfIsParam})
internalAssert c.config, tfVarargs in fntyp.flags
c.gABx(n, opcSetType, r, c.genType(n[i].typ))
else:
if fntyp[i] != nil and fntyp[i].kind == tySink and
fntyp[i].skipTypes({tySink}).kind in {tyObject, tyString, tySequence}:
c.gen(n[i], r, {gfIsSinkParam})
else:
c.gen(n[i], r, {gfIsParam})
if dest < 0:
c.gABC(n, opcIndCall, 0, x, n.len)
else:
@@ -1740,6 +1748,8 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
c.gABx(n, opcLdGlobalAddr, dest, s.position)
elif isImportcVar:
c.gABx(n, opcLdGlobalDerefFFI, dest, s.position)
elif gfIsSinkParam in flags:
genAsgn(c, dest, n, requiresCopy = true)
elif fitsRegister(s.typ) and gfNode notin flags:
var cc = c.getTemp(n.typ)
c.gABx(n, opcLdGlobal, cc, s.position)

View File

@@ -22,3 +22,49 @@ block: # bug #23902
proc foo(a: sink string) =
var x = (a, a)
block: # bug #24175
block:
func mutate(o: sink string): string =
o[1] = '1'
result = o
static:
let s = "999"
let m = mutate(s)
doAssert s == "999"
doAssert m == "919"
func foo() =
let s = "999"
let m = mutate(s)
doAssert s == "999"
doAssert m == "919"
static:
foo()
foo()
block:
type O = object
a: int
func mutate(o: sink O): O =
o.a += 1
o
static:
let x = O(a: 1)
let y = mutate(x)
doAssert x.a == 1
doAssert y.a == 2
proc foo() =
let x = O(a: 1)
let y = mutate(x)
doAssert x.a == 1
doAssert y.a == 2
static:
foo()
foo()