mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 14:00:35 +00:00
nil in string concats does not produce crashes anymore
This commit is contained in:
@@ -1034,7 +1034,7 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
||||
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
||||
inc(L, len(e.sons[i + 1].strVal))
|
||||
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)))
|
||||
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, rope(L))
|
||||
add(p.s(cpsStmts), appends)
|
||||
|
||||
@@ -161,14 +161,16 @@ proc hashString(s: string): int {.compilerproc.} =
|
||||
|
||||
proc addChar(s: NimString, c: char): NimString =
|
||||
# is compilerproc!
|
||||
result = s
|
||||
if result.len >= result.space:
|
||||
let r = resize(result.space)
|
||||
result = cast[NimString](growObj(result,
|
||||
sizeof(TGenericSeq) + r + 1))
|
||||
result.reserved = r
|
||||
elif wasMoved(s):
|
||||
result = newOwnedString(s, s.len)
|
||||
if s == nil:
|
||||
result = rawNewStringNoInit(1)
|
||||
result.len = 0
|
||||
else:
|
||||
result = s
|
||||
if result.len >= result.space:
|
||||
let r = resize(result.space)
|
||||
result = cast[NimString](growObj(result,
|
||||
sizeof(TGenericSeq) + r + 1))
|
||||
result.reserved = r
|
||||
result.data[result.len] = c
|
||||
result.data[result.len+1] = '\0'
|
||||
inc(result.len)
|
||||
@@ -205,7 +207,9 @@ proc addChar(s: NimString, c: char): NimString =
|
||||
# s = rawNewString(0);
|
||||
|
||||
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
|
||||
else: # slow path:
|
||||
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
|
||||
|
||||
proc appendString(dest, src: NimString) {.compilerproc, inline.} =
|
||||
copyMem(addr(dest.data[dest.len]), addr(src.data), src.len + 1)
|
||||
inc(dest.len, src.len)
|
||||
if src != nil:
|
||||
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.} =
|
||||
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
|
||||
Reference in New Issue
Block a user