diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index c9ab1ddcb..a58f59c51 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -194,10 +194,12 @@ proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType): (Rope, optSeqDestructors in p.config.globalOptions: linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)]) if atyp.kind in {tyVar} and not compileToCpp(p.module): - result = ("($4*)(*$1)$3+($2)" % [rdLoc(a), rdLoc(b), dataField(p), dest], + result = ("(($5) ? (($4*)(*$1)$3+($2)) : NIM_NIL)" % + [rdLoc(a), rdLoc(b), dataField(p), dest, dataFieldAccessor(p, "*" & rdLoc(a))], lengthExpr) else: - result = ("($4*)$1$3+($2)" % [rdLoc(a), rdLoc(b), dataField(p), dest], + result = ("(($5) ? (($4*)$1$3+($2)) : NIM_NIL)" % + [rdLoc(a), rdLoc(b), dataField(p), dest, dataFieldAccessor(p, rdLoc(a))], lengthExpr) else: internalError(p.config, "openArrayLoc: " & typeToString(a.t)) @@ -238,9 +240,12 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode; result: var Rope) = if ntyp.kind in {tyVar} and not compileToCpp(p.module): var t: TLoc t.r = "(*$1)" % [a.rdLoc] - result.add "(*$1)$3, $2" % [a.rdLoc, lenExpr(p, t), dataField(p)] + result.add "($4) ? ((*$1)$3) : NIM_NIL, $2" % + [a.rdLoc, lenExpr(p, t), dataField(p), + dataFieldAccessor(p, "*" & a.rdLoc)] else: - result.add "$1$3, $2" % [a.rdLoc, lenExpr(p, a), dataField(p)] + result.add "($4) ? ($1$3) : NIM_NIL, $2" % + [a.rdLoc, lenExpr(p, a), dataField(p), dataFieldAccessor(p, a.rdLoc)] of tyArray: result.add "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))] of tyPtr, tyRef: @@ -248,7 +253,9 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode; result: var Rope) = of tyString, tySequence: var t: TLoc t.r = "(*$1)" % [a.rdLoc] - result.add "(*$1)$3, $2" % [a.rdLoc, lenExpr(p, t), dataField(p)] + result.add "($4) ? ((*$1)$3) : NIM_NIL, $2" % + [a.rdLoc, lenExpr(p, t), dataField(p), + dataFieldAccessor(p, "*" & a.rdLoc)] of tyArray: result.add "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, lastSon(a.t)))] else: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index d3797b11d..dae04ba63 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -298,8 +298,8 @@ proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) = linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $2Len_0;$n", [rdLoc(d), a.rdLoc]) of tySequence: - linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n", - [rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)]) + linefmt(p, cpsStmts, "$1.Field0 = ($5) ? ($2$3) : NIM_NIL; $1.Field1 = $4;$n", + [rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a), dataFieldAccessor(p, a.rdLoc)]) of tyArray: linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n", [rdLoc(d), rdLoc(a), rope(lengthOrd(p.config, a.t))]) @@ -308,8 +308,8 @@ proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) = if etyp.kind in {tyVar} and optSeqDestructors in p.config.globalOptions: linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)]) - linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n", - [rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)]) + linefmt(p, cpsStmts, "$1.Field0 = ($5) ? ($2$3) : NIM_NIL; $1.Field1 = $4;$n", + [rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a), dataFieldAccessor(p, a.rdLoc)]) else: internalError(p.config, a.lode.info, "cannot handle " & $a.t.kind) @@ -1792,7 +1792,9 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, b, e, "$1, $1Len_0" % [rdLoc(a)], a.storage) of tyString, tySequence: putIntoDest(p, b, e, - "$1$3, $2" % [rdLoc(a), lenExpr(p, a), dataField(p)], a.storage) + "($4) ? ($1$3) : NIM_NIL, $2" % + [rdLoc(a), lenExpr(p, a), dataField(p), dataFieldAccessor(p, a.rdLoc)], + a.storage) of tyArray: putIntoDest(p, b, e, "$1, $2" % [rdLoc(a), rope(lengthOrd(p.config, a.t))], a.storage) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 5fc42bfec..6fa60cbcd 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -322,6 +322,12 @@ proc lenExpr(p: BProc; a: TLoc): Rope = else: result = "($1 ? $1->$2 : 0)" % [rdLoc(a), lenField(p)] +proc dataFieldAccessor(p: BProc, sym: Rope): Rope = + if optSeqDestructors in p.config.globalOptions: + result = "(" & sym & ").p" + else: + result = sym + proc dataField(p: BProc): Rope = if optSeqDestructors in p.config.globalOptions: result = rope".p->data"