diff options
-rw-r--r-- | compiler/semexprs.nim | 4 | ||||
-rw-r--r-- | tests/ccgbugs2/tcodegen.nim | 75 |
2 files changed, 49 insertions, 30 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 8cdd16f02..e6983910d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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: diff --git a/tests/ccgbugs2/tcodegen.nim b/tests/ccgbugs2/tcodegen.nim index 84cd76e2f..aac1ecaf3 100644 --- a/tests/ccgbugs2/tcodegen.nim +++ b/tests/ccgbugs2/tcodegen.nim @@ -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() |