Skip to content

Commit

Permalink
[backport] fixes nim-lang#23748; do not skip materializing temporarie…
Browse files Browse the repository at this point in the history
…s for proc arguments (nim-lang#23769)

fixes nim-lang#23748
  • Loading branch information
alex65536 authored and Graveflo committed Jul 1, 2024
1 parent 28163ac commit 0cb361c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
19 changes: 15 additions & 4 deletions compiler/ccgcalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
31 changes: 31 additions & 0 deletions tests/destructor/t23748.nim
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 0cb361c

Please sign in to comment.