diff options
-rw-r--r-- | compiler/ccgexprs.nim | 40 | ||||
-rw-r--r-- | compiler/cgen.nim | 9 | ||||
-rw-r--r-- | tests/ccgbugs/t6279.nim | 9 | ||||
-rw-r--r-- | tests/ccgbugs/taddhigh.nim | 5 |
4 files changed, 57 insertions, 6 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index fbdd5f318..74f8f90cd 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1061,7 +1061,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = "$1 = ($2) #incrSeqV2(&($1)->Sup, sizeof($3));$n" else: "$1 = ($2) #incrSeqV2($1, sizeof($3));$n" - var a, b, dest: TLoc + var a, b, dest, tmpL: TLoc initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) let bt = skipTypes(e.sons[2].typ, {tyVar}) @@ -1072,9 +1072,10 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = #if bt != b.t: # echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t) initLoc(dest, locExpr, bt, OnHeap) - dest.r = rfmt(nil, "$1->data[$1->$2]", rdLoc(a), lenField(p)) + getIntTemp(p, tmpL) + lineCg(p, cpsStmts, "$1 = $2->$3++;$n", tmpL.r, rdLoc(a), lenField(p)) + dest.r = rfmt(nil, "$1->data[$2]", rdLoc(a), tmpL.r) genAssignment(p, dest, b, {needToCopy, afDestIsNil}) - lineCg(p, cpsStmts, "++$1->$2;$n", rdLoc(a), lenField(p)) gcUsage(e) proc genReset(p: BProc, n: PNode) = @@ -1382,13 +1383,30 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = useStringh(p.module) if op == mHigh: unaryExpr(p, e, d, "($1 ? (strlen($1)-1) : -1)") else: unaryExpr(p, e, d, "($1 ? strlen($1) : 0)") - of tyString, tySequence: + of tyString: if not p.module.compileToCpp: if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->Sup.len-1) : -1)") else: unaryExpr(p, e, d, "($1 ? $1->Sup.len : 0)") else: if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->len-1) : -1)") else: unaryExpr(p, e, d, "($1 ? $1->len : 0)") + of tySequence: + var a, tmp: TLoc + initLocExpr(p, e[1], a) + getIntTemp(p, tmp) + var frmt: FormatStr + if not p.module.compileToCpp: + if op == mHigh: + frmt = "$1 = ($2 ? ($2->Sup.len-1) : -1);$n" + else: + frmt = "$1 = ($2 ? $2->Sup.len : 0);$n" + else: + if op == mHigh: + frmt = "$1 = ($2 ? ($2->len-1) : -1);$n" + else: + frmt = "$1 = ($2 ? $2->len : 0);$n" + lineCg(p, cpsStmts, frmt, tmp.r, rdLoc(a)) + putIntoDest(p, d, e.typ, tmp.r) of tyArray: # YYY: length(sideeffect) is optimized away incorrectly? if op == mHigh: putIntoDest(p, d, e.typ, rope(lastOrd(typ))) @@ -1746,11 +1764,23 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mOrd: genOrd(p, e, d) of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray: genArrayLen(p, e, d, op) - of mXLenStr, mXLenSeq: + of mXLenStr: if not p.module.compileToCpp: unaryExpr(p, e, d, "($1->Sup.len)") else: unaryExpr(p, e, d, "$1->len") + of mXLenSeq: + # see 'taddhigh.nim' for why we need to use a temporary here: + var a, tmp: TLoc + initLocExpr(p, e[1], a) + getIntTemp(p, tmp) + var frmt: FormatStr + if not p.module.compileToCpp: + frmt = "$1 = $2->Sup.len;$n" + else: + frmt = "$1 = $2->len;$n" + lineCg(p, cpsStmts, frmt, tmp.r, rdLoc(a)) + putIntoDest(p, d, e.typ, tmp.r) of mGCref: unaryStmt(p, e, d, "#nimGCref($1);$n") of mGCunref: unaryStmt(p, e, d, "#nimGCunref($1);$n") of mSetLengthStr: genSetLengthStr(p, e, d) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index a7a801560..39c14347b 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -345,6 +345,15 @@ proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) = result.flags = {} constructLoc(p, result, not needsInit) +proc getIntTemp(p: BProc, result: var TLoc) = + inc(p.labels) + result.r = "T" & rope(p.labels) & "_" + linefmt(p, cpsLocals, "NI $1;$n", result.r) + result.k = locTemp + result.s = OnStack + result.t = getSysType(tyInt) + result.flags = {} + proc initGCFrame(p: BProc): Rope = if p.gcFrameId > 0: result = "struct {$1} GCFRAME_;$n" % [p.gcFrameType] diff --git a/tests/ccgbugs/t6279.nim b/tests/ccgbugs/t6279.nim new file mode 100644 index 000000000..37345d807 --- /dev/null +++ b/tests/ccgbugs/t6279.nim @@ -0,0 +1,9 @@ +discard """ +cmd: "nim c -r -d:fulldebug -d:smokeCycles --gc:refc $file" +output: '''@[a]''' +""" + +# bug #6279 +var foo = newSeq[tuple[a: seq[string], b: seq[string]]]() +foo.add((@["a"], @["b"])) +echo foo[0].a # Crashes on this line diff --git a/tests/ccgbugs/taddhigh.nim b/tests/ccgbugs/taddhigh.nim index d6ac8f650..549eb8caa 100644 --- a/tests/ccgbugs/taddhigh.nim +++ b/tests/ccgbugs/taddhigh.nim @@ -1,5 +1,5 @@ discard """ - output: '''@[5, 5, 5]''' + output: '''@[5, 5, 5, 5, 5]''' """ # bug #1832 @@ -13,4 +13,7 @@ s.add x # Causes the 0 to appear: s.add s[s.high] +s.add s[s.len-1] +s.add s[s.xlen-1] + echo s # @[5, 5, 0] |