From 9f95dd8e1d8a43bbb790dc6ec9aa6668b01230c6 Mon Sep 17 00:00:00 2001 From: Brandon Pickering Date: Sat, 14 Jan 2017 21:26:59 -0800 Subject: [PATCH] Create temp var in deepcopy if needed (#5205) --- compiler/ccgexprs.nim | 13 +++++++++++-- tests/ccgbugs/tdeepcopy_addr_rval.nim | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/ccgbugs/tdeepcopy_addr_rval.nim diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 58c0d745c3..eabcdd66ad 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 0000000000..07fb8f8ef7 --- /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