nil in string concats does not produce crashes anymore
This commit is contained in:
parent
c8a412998a
commit
7c538b26ad
3 changed files with 42 additions and 12 deletions
|
|
@ -1034,7 +1034,7 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
inc(L, len(e.sons[i + 1].strVal))
|
inc(L, len(e.sons[i + 1].strVal))
|
||||||
else:
|
else:
|
||||||
addf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
|
addf(lens, "($1 ? $1->$2 : 0) + ", [rdLoc(a), lenField(p)])
|
||||||
add(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
|
add(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
|
||||||
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, rope(L))
|
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, rope(L))
|
||||||
add(p.s(cpsStmts), appends)
|
add(p.s(cpsStmts), appends)
|
||||||
|
|
|
||||||
|
|
@ -161,14 +161,16 @@ proc hashString(s: string): int {.compilerproc.} =
|
||||||
|
|
||||||
proc addChar(s: NimString, c: char): NimString =
|
proc addChar(s: NimString, c: char): NimString =
|
||||||
# is compilerproc!
|
# is compilerproc!
|
||||||
result = s
|
if s == nil:
|
||||||
if result.len >= result.space:
|
result = rawNewStringNoInit(1)
|
||||||
let r = resize(result.space)
|
result.len = 0
|
||||||
result = cast[NimString](growObj(result,
|
else:
|
||||||
sizeof(TGenericSeq) + r + 1))
|
result = s
|
||||||
result.reserved = r
|
if result.len >= result.space:
|
||||||
elif wasMoved(s):
|
let r = resize(result.space)
|
||||||
result = newOwnedString(s, s.len)
|
result = cast[NimString](growObj(result,
|
||||||
|
sizeof(TGenericSeq) + r + 1))
|
||||||
|
result.reserved = r
|
||||||
result.data[result.len] = c
|
result.data[result.len] = c
|
||||||
result.data[result.len+1] = '\0'
|
result.data[result.len+1] = '\0'
|
||||||
inc(result.len)
|
inc(result.len)
|
||||||
|
|
@ -205,7 +207,9 @@ proc addChar(s: NimString, c: char): NimString =
|
||||||
# s = rawNewString(0);
|
# s = rawNewString(0);
|
||||||
|
|
||||||
proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} =
|
proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} =
|
||||||
if dest.len + addlen <= dest.space and not wasMoved(dest):
|
if dest == nil:
|
||||||
|
result = rawNewStringNoInit(addlen)
|
||||||
|
elif dest.len + addlen <= dest.space and not wasMoved(dest):
|
||||||
result = dest
|
result = dest
|
||||||
else: # slow path:
|
else: # slow path:
|
||||||
var sp = max(resize(dest.space), dest.len + addlen)
|
var sp = max(resize(dest.space), dest.len + addlen)
|
||||||
|
|
@ -216,8 +220,9 @@ proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} =
|
||||||
# DO NOT UPDATE LEN YET: dest.len = newLen
|
# DO NOT UPDATE LEN YET: dest.len = newLen
|
||||||
|
|
||||||
proc appendString(dest, src: NimString) {.compilerproc, inline.} =
|
proc appendString(dest, src: NimString) {.compilerproc, inline.} =
|
||||||
copyMem(addr(dest.data[dest.len]), addr(src.data), src.len + 1)
|
if src != nil:
|
||||||
inc(dest.len, src.len)
|
copyMem(addr(dest.data[dest.len]), addr(src.data), src.len + 1)
|
||||||
|
inc(dest.len, src.len)
|
||||||
|
|
||||||
proc appendChar(dest: NimString, c: char) {.compilerproc, inline.} =
|
proc appendChar(dest: NimString, c: char) {.compilerproc, inline.} =
|
||||||
dest.data[dest.len] = c
|
dest.data[dest.len] = c
|
||||||
|
|
|
||||||
25
tests/system/tnilconcats.nim
Normal file
25
tests/system/tnilconcats.nim
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
discard """
|
||||||
|
output: '''@[nil, nil, nil, nil, nil, nil, nil, "meh"]'''
|
||||||
|
exitcode: "0"
|
||||||
|
"""
|
||||||
|
|
||||||
|
when true:
|
||||||
|
var ab: string
|
||||||
|
ab &= "more"
|
||||||
|
|
||||||
|
doAssert ab == "more"
|
||||||
|
|
||||||
|
var x: seq[string]
|
||||||
|
|
||||||
|
setLen(x, 7)
|
||||||
|
|
||||||
|
x.add "meh"
|
||||||
|
|
||||||
|
var s: string
|
||||||
|
var z = "abc"
|
||||||
|
var zz: string
|
||||||
|
s &= "foo" & z & zz
|
||||||
|
|
||||||
|
doAssert s == "fooabc"
|
||||||
|
|
||||||
|
echo x
|
||||||
Loading…
Add table
Add a link
Reference in a new issue