diff options
-rw-r--r-- | compiler/ccgexprs.nim | 48 | ||||
-rw-r--r-- | tests/objects/tobjconstr.nim | 7 | ||||
-rw-r--r-- | tests/objects/tobjconstr2.nim | 7 |
3 files changed, 45 insertions, 17 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 0a312b4c7..bb9a9f6c6 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1202,18 +1202,30 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = # we skip this step here: if not p.module.compileToCpp: if handleConstExpr(p, e, d): return - var tmp: TLoc var t = e.typ.skipTypes(abstractInst) - getTemp(p, t, tmp) let isRef = t.kind == tyRef - var r = rdLoc(tmp) - if isRef: - rawGenNew(p, tmp, nil) - t = t.lastSon.skipTypes(abstractInst) - r = "(*$1)" % [r] - gcUsage(e) + + # check if we need to construct the object in a temporary + var useTemp = + isRef or + (d.k notin {locTemp,locLocalVar,locGlobalVar,locParam,locField}) or + (isPartOf(d.lode, e) != arNo) + + var tmp: TLoc + var r: Rope + if useTemp: + getTemp(p, t, tmp) + r = rdLoc(tmp) + if isRef: + rawGenNew(p, tmp, nil) + t = t.lastSon.skipTypes(abstractInst) + r = "(*$1)" % [r] + gcUsage(e) + else: + constructLoc(p, tmp) else: - constructLoc(p, tmp) + resetLoc(p, d) + r = rdLoc(d) discard getTypeDesc(p.module, t) let ty = getUniqueType(t) for i in 1 ..< e.len: @@ -1227,15 +1239,19 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = genFieldCheck(p, it.sons[2], r, field) add(tmp2.r, ".") add(tmp2.r, field.loc.r) - tmp2.k = locTemp + if useTemp: + tmp2.k = locTemp + tmp2.storage = if isRef: OnHeap else: OnStack + else: + tmp2.k = d.k + tmp2.storage = if isRef: OnHeap else: d.storage tmp2.lode = it.sons[1] - tmp2.storage = if isRef: OnHeap else: OnStack expr(p, it.sons[1], tmp2) - - if d.k == locNone: - d = tmp - else: - genAssignment(p, d, tmp, {}) + if useTemp: + if d.k == locNone: + d = tmp + else: + genAssignment(p, d, tmp, {}) proc lhsDoesAlias(a, b: PNode): bool = for y in b: diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim index b7da176aa..d1f3c8bdb 100644 --- a/tests/objects/tobjconstr.nim +++ b/tests/objects/tobjconstr.nim @@ -15,7 +15,8 @@ discard """ (y: 678, x: 123) (y: 678, x: 123) (y: 0, x: 123) -(y: 678, x: 123)''' +(y: 678, x: 123) +(y: 123, x: 678)''' """ type @@ -75,3 +76,7 @@ when true: echo b # (y: 0, x: 123) b=B(y: 678, x: 123) echo b # (y: 678, x: 123) + b=B(y: b.x, x: b.y) + echo b # (y: 123, x: 678) + +GC_fullCollect() diff --git a/tests/objects/tobjconstr2.nim b/tests/objects/tobjconstr2.nim index f6805190b..6253edab0 100644 --- a/tests/objects/tobjconstr2.nim +++ b/tests/objects/tobjconstr2.nim @@ -1,3 +1,8 @@ +discard """ + output: '''42 +Foo''' +""" + type TFoo{.exportc.} = object x:int @@ -48,3 +53,5 @@ type NamedGraphic = object of Graphic2 var ngr = NamedGraphic(kind: Koo, radius: 6.9, name: "Foo") echo ngr.name + +GC_fullCollect() |