[backport] fixes #23748; do not skip materializing temporaries for proc arguments (#23769)

fixes #23748
This commit is contained in:
Alexander Kernozhitsky
2024-06-30 14:10:10 +02:00
committed by GitHub
parent c88894bf76
commit 4202b606b1
3 changed files with 48 additions and 4 deletions

View File

@@ -331,7 +331,16 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; need
addAddrLoc(p.config, withTmpIfNeeded(p, a, needsTmp), result)
elif p.module.compileToCpp and param.typ.kind in {tyVar} and
n.kind == nkHiddenAddr:
a = initLocExprSingleUse(p, n[0])
# bug #23748: we need to introduce a temporary here. The expression type
# will be a reference in C++ and we cannot create a temporary reference
# variable. Thus, we create a temporary pointer variable instead.
let needsIndirect = mapType(p.config, n[0].typ, mapTypeChooser(n[0]) == skParam) != ctArray
if needsIndirect:
n.typ = n.typ.exactReplica
n.typ.flags.incl tfVarIsPtr
a = initLocExprSingleUse(p, n)
a = withTmpIfNeeded(p, a, needsTmp)
if needsIndirect: a.flags.incl lfIndirect
# if the proc is 'importc'ed but not 'importcpp'ed then 'var T' still
# means '*T'. See posix.nim for lots of examples that do that in the wild.
let callee = call[0]
@@ -430,9 +439,11 @@ proc genParams(p: BProc, ri: PNode, typ: PType; result: var Rope) =
if not needTmp[i - 1]:
needTmp[i - 1] = potentialAlias(n, potentialWrites)
getPotentialWrites(ri[i], false, potentialWrites)
if ri[i].kind in {nkHiddenAddr, nkAddr}:
# Optimization: don't use a temp, if we would only take the address anyway
needTmp[i - 1] = false
when false:
# this optimization is wrong, see bug #23748
if ri[i].kind in {nkHiddenAddr, nkAddr}:
# Optimization: don't use a temp, if we would only take the address anyway
needTmp[i - 1] = false
var oldLen = result.len
for i in 1..<ri.len:

View File

@@ -812,6 +812,8 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) =
#Message(e.info, warnUser, "HERE NEW &")
elif mapType(p.config, e[0].typ, mapTypeChooser(e[0]) == skParam) == ctArray or isCppRef(p, e.typ):
expr(p, e[0], d)
# bug #19497
d.lode = e
else:
var a: TLoc = initLocExpr(p, e[0])
putIntoDest(p, d, e, addrLoc(p.config, a), a.storage)

View File

@@ -0,0 +1,31 @@
discard """
matrix: "--gc:refc; --gc:arc"
output: '''
hello 42
hello 42
len = 2
'''
"""
# bug #23748
type
O = ref object
s: string
cb: seq[proc()]
proc push1(o: O, i: int) =
let o = o
echo o.s, " ", i
o.cb.add(proc() = echo o.s, " ", i)
proc push2(o: O, i: int) =
let o = o
echo o.s, " ", i
proc p() = echo o.s, " ", i
o.cb.add(p)
let o = O(s: "hello", cb: @[])
o.push1(42)
o.push2(42)
echo "len = ", o.cb.len