diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 288ce1c99..c237eeffa 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1052,9 +1052,9 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = # seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x)); # seq->data[seq->len-1] = x; let seqAppendPattern = if not p.module.compileToCpp: - "$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n" + "$1 = ($2) #incrSeqV2(&($1)->Sup, sizeof($3));$n" else: - "$1 = ($2) #incrSeq($1, sizeof($3));$n" + "$1 = ($2) #incrSeqV2($1, sizeof($3));$n" var a, b, dest: TLoc initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], b) @@ -1064,8 +1064,9 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = getTypeDesc(p.module, skipTypes(e.sons[2].typ, abstractVar))]) keepAlive(p, a) initLoc(dest, locExpr, b.t, OnHeap) - dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField(p)) + dest.r = rfmt(nil, "$1->data[$1->$2]", rdLoc(a), lenField(p)) genAssignment(p, dest, b, {needToCopy, afDestIsNil}) + lineCg(p, cpsStmts, "++$1->$2;$n", rdLoc(a), lenField(p)) gcUsage(e) proc genReset(p: BProc, n: PNode) = diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 33629016f..326c601bd 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -210,6 +210,14 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} = GenericSeqSize)) inc(result.len) +proc incrSeqV2(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} = + # incrSeq version 2 + result = seq + if result.len >= result.space: + result.reserved = resize(result.space) + result = cast[PGenericSeq](growObj(result, elemSize * result.reserved + + GenericSeqSize)) + proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. compilerRtl.} = result = seq diff --git a/tests/ccgbugs/taddhigh.nim b/tests/ccgbugs/taddhigh.nim new file mode 100644 index 000000000..d6ac8f650 --- /dev/null +++ b/tests/ccgbugs/taddhigh.nim @@ -0,0 +1,16 @@ +discard """ + output: '''@[5, 5, 5]''' +""" + +# bug #1832 + +var s = @[5] + +# Works fine: +let x = s[s.high] +s.add x + +# Causes the 0 to appear: +s.add s[s.high] + +echo s # @[5, 5, 0]