From c9d7c67acbcb08bd3ca656f6f82b1b474781ee69 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 17 Dec 2020 23:21:55 +0100 Subject: [PATCH] fixes #16365 [backport] (#16381) (cherry picked from commit 868c31e88a68ce16c5c0d9283a41fb3cfcec4c41) --- lib/system/strs_v2.nim | 13 ++++----- tests/destructor/tnewruntime_strutils.nim | 32 ++++++++++++++++++++++- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/system/strs_v2.nim b/lib/system/strs_v2.nim index f51791da2c22..fe117997bf0a 100644 --- a/lib/system/strs_v2.nim +++ b/lib/system/strs_v2.nim @@ -40,21 +40,22 @@ proc resize(old: int): int {.inline.} = else: result = old * 3 div 2 # for large arrays * 3/2 is better proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} = + let newLen = s.len + addlen if isLiteral(s): let oldP = s.p # can't mutate a literal, so we need a fresh copy here: when compileOption("threads"): - s.p = cast[ptr NimStrPayload](allocShared0(contentSize(s.len + addlen))) + s.p = cast[ptr NimStrPayload](allocShared0(contentSize(newLen))) else: - s.p = cast[ptr NimStrPayload](alloc0(contentSize(s.len + addlen))) - s.p.cap = s.len + addlen + s.p = cast[ptr NimStrPayload](alloc0(contentSize(newLen))) + s.p.cap = newLen if s.len > 0: # we are about to append, so there is no need to copy the \0 terminator: - copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len) + copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], min(s.len, newLen)) else: let oldCap = s.p.cap and not strlitFlag - if s.len + addlen > oldCap: - let newCap = max(s.len + addlen, resize(oldCap)) + if newLen > oldCap: + let newCap = max(newLen, resize(oldCap)) when compileOption("threads"): s.p = cast[ptr NimStrPayload](reallocShared0(s.p, contentSize(oldCap), contentSize(newCap))) else: diff --git a/tests/destructor/tnewruntime_strutils.nim b/tests/destructor/tnewruntime_strutils.nim index b0bceb4b5b76..0725718d759d 100644 --- a/tests/destructor/tnewruntime_strutils.nim +++ b/tests/destructor/tnewruntime_strutils.nim @@ -2,7 +2,10 @@ discard """ valgrind: true cmd: '''nim c -d:nimAllocStats --newruntime -d:useMalloc $file''' output: ''' -@[(input: @["KXSC", "BGMC"]), (input: @["PXFX"]), (input: @["WXRQ", "ZSCZD"])]''' +@[(input: @["KXSC", "BGMC"]), (input: @["PXFX"]), (input: @["WXRQ", "ZSCZD"])] +14 +First tasks completed. +Second tasks completed.''' """ import strutils, os, std / wordwrap @@ -211,3 +214,30 @@ staticTests() # bug #12965 let xaa = @[""].join() let xbb = @["", ""].join() + +# bug #16365 + +# Task 1: +when true: + # Task 1_a: + var test_string_a = "name_something" + echo test_string_a.len() + let new_len_a = test_string_a.len - "_something".len() + test_string_a.setLen new_len_a + + echo "First tasks completed." + +# Task 2: +when true: + # Task 2_a + var test_string: string + let some_string = "something" + for i in some_string.items: + test_string.add $i + + # Task 2_b + var test_string_b = "name_something" + let new_len_b = test_string_b.len - "_something".len() + test_string_b.setLen new_len_b + + echo "Second tasks completed."