summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgexprs.nim18
-rw-r--r--tests/destructor/tmove.nim18
2 files changed, 33 insertions, 3 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index dd47d1d1f..64bd16f84 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -2310,9 +2310,21 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) =
       if op == nil:
         resetLoc(p, a)
       else:
-        let addrExp = makeAddr(n[1], p.module.idgen)
-        let wasMovedCall = newTreeI(nkCall, n.info, newSymNode(op), addrExp)
-        genCall(p, wasMovedCall, d)
+        var b = initLocExpr(p, newSymNode(op))
+        case skipTypes(a.t, abstractVar+{tyStatic}).kind
+        of tyOpenArray, tyVarargs: # todo fixme generated `wasMoved` hooks for
+                                   # openarrays, but it probably shouldn't?
+          var s: string
+          if reifiedOpenArray(a.lode):
+            if a.t.kind in {tyVar, tyLent}:
+              s = "$1->Field0, $1->Field1" % [rdLoc(a)]
+            else:
+              s = "$1.Field0, $1.Field1" % [rdLoc(a)]
+          else:
+            s = "$1, $1Len_0" % [rdLoc(a)]
+          linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), s])
+        else:
+          linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), byRefLoc(p, a)])
     else:
       let flags = if not canMove(p, n[1], d): {needToCopy} else: {}
       genAssignment(p, d, a, flags)
diff --git a/tests/destructor/tmove.nim b/tests/destructor/tmove.nim
new file mode 100644
index 000000000..2762aff90
--- /dev/null
+++ b/tests/destructor/tmove.nim
@@ -0,0 +1,18 @@
+discard """
+  targets: "c cpp"
+"""
+
+block:
+  var called = 0
+
+  proc bar(a: var int): var int =
+    inc called
+    result = a
+
+  proc foo =
+    var a = 2
+    var s = move bar(a)
+    doAssert called == 1
+    doAssert s == 2
+
+  foo()