diff options
-rw-r--r-- | compiler/ccgexprs.nim | 13 | ||||
-rw-r--r-- | tests/ccgbugs/tdeepcopy_addr_rval.nim | 16 |
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 |