mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
fixes #23748
This commit is contained in:
committed by
GitHub
parent
c88894bf76
commit
4202b606b1
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
31
tests/destructor/t23748.nim
Normal file
31
tests/destructor/t23748.nim
Normal 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
|
||||
Reference in New Issue
Block a user