mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 03:44:14 +00:00
fixes #22354 It skips `nkHiddenAddr`. No need to hoist `var parameters` without side effects. Besides, it saves lots of temporary variables in ORC.
This commit is contained in:
@@ -2927,7 +2927,7 @@ proc hoistParamsUsedInDefault(c: PContext, call, letSection, defExpr: var PNode)
|
||||
if defExpr.kind == nkSym and defExpr.sym.kind == skParam and defExpr.sym.owner == call[0].sym:
|
||||
let paramPos = defExpr.sym.position + 1
|
||||
|
||||
if call[paramPos].kind != nkSym:
|
||||
if call[paramPos].skipAddr.kind != nkSym:
|
||||
let hoistedVarSym = newSym(skLet, getIdent(c.graph.cache, genPrefix), c.idgen,
|
||||
c.p.owner, letSection.info, c.p.owner.options)
|
||||
hoistedVarSym.typ = call[paramPos].typ
|
||||
@@ -2939,7 +2939,7 @@ proc hoistParamsUsedInDefault(c: PContext, call, letSection, defExpr: var PNode)
|
||||
|
||||
call[paramPos] = newSymNode(hoistedVarSym) # Refer the original arg to its hoisted sym
|
||||
|
||||
# arg we refer to is a sym, wether introduced by hoisting or not doesn't matter, we simply reuse it
|
||||
# arg we refer to is a sym, whether introduced by hoisting or not doesn't matter, we simply reuse it
|
||||
defExpr = call[paramPos]
|
||||
else:
|
||||
for i in 0..<defExpr.safeLen:
|
||||
|
||||
@@ -1,28 +1,47 @@
|
||||
discard """
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
# bug #19094
|
||||
type
|
||||
X = object
|
||||
filler: array[2048, int]
|
||||
innerAddress: uint
|
||||
|
||||
proc initX(): X =
|
||||
result.innerAddress = cast[uint](result.addr)
|
||||
|
||||
proc initXInPlace(x: var X) =
|
||||
x.innerAddress = cast[uint](x.addr)
|
||||
|
||||
block: # NRVO1
|
||||
var x = initX()
|
||||
let innerAddress = x.innerAddress
|
||||
let outerAddress = cast[uint](x.addr)
|
||||
doAssert(innerAddress == outerAddress) # [OK]
|
||||
|
||||
block: # NRVO2
|
||||
var x: X
|
||||
initXInPlace(x)
|
||||
let innerAddress = x.innerAddress
|
||||
let outerAddress = cast[uint](x.addr)
|
||||
doAssert(innerAddress == outerAddress) # [OK]
|
||||
discard """
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
# bug #19094
|
||||
type
|
||||
X = object
|
||||
filler: array[2048, int]
|
||||
innerAddress: uint
|
||||
|
||||
proc initX(): X =
|
||||
result.innerAddress = cast[uint](result.addr)
|
||||
|
||||
proc initXInPlace(x: var X) =
|
||||
x.innerAddress = cast[uint](x.addr)
|
||||
|
||||
block: # NRVO1
|
||||
var x = initX()
|
||||
let innerAddress = x.innerAddress
|
||||
let outerAddress = cast[uint](x.addr)
|
||||
doAssert(innerAddress == outerAddress) # [OK]
|
||||
|
||||
block: # NRVO2
|
||||
var x: X
|
||||
initXInPlace(x)
|
||||
let innerAddress = x.innerAddress
|
||||
let outerAddress = cast[uint](x.addr)
|
||||
doAssert(innerAddress == outerAddress) # [OK]
|
||||
|
||||
block: # bug #22354
|
||||
type Object = object
|
||||
foo: int
|
||||
|
||||
proc takeFoo(self: var Object): int =
|
||||
result = self.foo
|
||||
self.foo = 999
|
||||
|
||||
proc doSomething(self: var Object; foo: int = self.takeFoo()) =
|
||||
discard
|
||||
|
||||
proc main() =
|
||||
var obj = Object(foo: 2)
|
||||
obj.doSomething()
|
||||
doAssert obj.foo == 999
|
||||
|
||||
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user