summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--tests/ccgbugs2/tcodegen.nim75
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()