summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBrandon Pickering <brandonpickering95@gmail.com>2017-01-14 21:26:59 -0800
committerAndreas Rumpf <rumpf_a@web.de>2017-01-15 06:26:59 +0100
commit9f95dd8e1d8a43bbb790dc6ec9aa6668b01230c6 (patch)
treecc7b62194cfef4092e762f5f4161d39472e9a424
parent03916fa3b1a07eb4cbd88cf3afe359695caf5446 (diff)
downloadNim-9f95dd8e1d8a43bbb790dc6ec9aa6668b01230c6.tar.gz
Create temp var in deepcopy if needed (#5205)
-rw-r--r--compiler/ccgexprs.nim13
-rw-r--r--tests/ccgbugs/tdeepcopy_addr_rval.nim16
2 files changed, 27 insertions, 2 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 58c0d745c..eabcdd66a 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -363,19 +363,28 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
             rope p.currLineInfo.safeLineNm)
 
 proc genDeepCopy(p: BProc; dest, src: TLoc) =
+  template addrLocOrTemp(a: TLoc): Rope =
+    if a.k == locExpr:
+      var tmp: TLoc
+      getTemp(p, a.t, tmp)
+      genAssignment(p, tmp, a, {})
+      addrLoc(tmp)
+    else:
+      addrLoc(a)
+
   var ty = skipTypes(dest.t, abstractVarRange)
   case ty.kind
   of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
     # XXX optimize this
     linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
-            addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
+            addrLoc(dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t))
   of tySequence, tyString:
     linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n",
             addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t))
   of tyOpenArray, tyVarargs:
     linefmt(p, cpsStmts,
          "#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n",
-         addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t))
+         addrLoc(dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t))
   of tySet:
     if mapType(ty) == ctArray:
       useStringh(p.module)
diff --git a/tests/ccgbugs/tdeepcopy_addr_rval.nim b/tests/ccgbugs/tdeepcopy_addr_rval.nim
new file mode 100644
index 000000000..07fb8f8ef
--- /dev/null
+++ b/tests/ccgbugs/tdeepcopy_addr_rval.nim
@@ -0,0 +1,16 @@
+discard """
+  output: "3"
+"""
+
+# issue 5166
+
+type
+  Test = ref object
+    x: int
+
+let x = Test(x: 3)
+let p = cast[pointer](x)
+
+var v: Test
+deepCopy(v, cast[Test](p))
+echo v.x