summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-04-27 09:57:14 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-04-27 09:57:20 +0200
commitef1b547f358ce610e8f728a05169a2ee434b8f87 (patch)
tree1e34d9b7b959c3467e504f2848d0946af5f4c675
parentc71c951a64c8c0adc6f6ae9992bc8bfeb003a31f (diff)
downloadNim-ef1b547f358ce610e8f728a05169a2ee434b8f87.tar.gz
'add' on a nil sequence doesn't produce a crash anymore
-rw-r--r--compiler/ccgexprs.nim8
-rw-r--r--lib/system/sysstr.nim12
2 files changed, 16 insertions, 4 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index ea373f5a6..ef21743d8 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1086,17 +1086,17 @@ 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) #incrSeqV2(&($1)->Sup, sizeof($3));$n"
+                           "$1 = ($2) #incrSeqV3(&($1)->Sup, $3);$n"
                          else:
-                           "$1 = ($2) #incrSeqV2($1, sizeof($3));$n"
+                           "$1 = ($2) #incrSeqV3($1, $3);$n"
   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})
+  let seqType = skipTypes(e.sons[1].typ, {tyVar})
   lineCg(p, cpsStmts, seqAppendPattern, [
       rdLoc(a),
       getTypeDesc(p.module, e.sons[1].typ),
-      getTypeDesc(p.module, bt)])
+      genTypeInfo(p.module, seqType, e.info)])
   #if bt != b.t:
   #  echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t)
   initLoc(dest, locExpr, e.sons[2], OnHeap)
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index ea0273340..7640b888b 100644
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -261,6 +261,18 @@ proc incrSeqV2(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
                                GenericSeqSize))
     result.reserved = r
 
+proc incrSeqV3(s: PGenericSeq, typ: PNimType): PGenericSeq {.compilerProc.} =
+  if s == nil:
+    result = cast[PGenericSeq](newSeq(typ, 1))
+    result.len = 0
+  else:
+    result = s
+    if result.len >= result.space:
+      let r = resize(result.space)
+      result = cast[PGenericSeq](growObj(result, typ.base.size * r +
+                                GenericSeqSize))
+      result.reserved = r
+
 proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
     compilerRtl, inl.} =
   result = seq