This commit is contained in:
Andreas Rumpf
2019-08-10 15:41:24 +02:00
parent 0e4a8bfb28
commit 212ae2f125
5 changed files with 26 additions and 2 deletions

View File

@@ -759,7 +759,9 @@ type
lfImportCompilerProc, # ``importc`` of a compilerproc
lfSingleUse # no location yet and will only be used once
lfEnforceDeref # a copyMem is required to dereference if this a
# ptr array due to C array limitations. See #1181, #6422, #11171
# ptr array due to C array limitations.
# See #1181, #6422, #11171
lfPrepareForMutation # string location is about to be mutated (V2)
TStorageLoc* = enum
OnUnknown, # location is unknown (stack, heap or static)
OnStatic, # in a static section

View File

@@ -944,6 +944,10 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
if d.k == locNone: d.storage = OnHeap
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
a.r = ropecg(p.module, "(*$1)", [a.r])
if lfPrepareForMutation in d.flags and ty.kind == tyString and
p.config.selectedGC == gcDestructors:
linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
putIntoDest(p, d, n,
ropecg(p.module, "$1$3[$2]", [rdLoc(a), rdCharLoc(b), dataField(p)]), a.storage)

View File

@@ -1266,11 +1266,13 @@ proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
discard getTypeDesc(p.module, le.typ.skipTypes(skipPtrs))
initLoc(a, locNone, le, OnUnknown)
a.flags.incl(lfEnforceDeref)
a.flags.incl(lfPrepareForMutation)
expr(p, le, a)
a.flags.excl(lfPrepareForMutation)
if fastAsgn: incl(a.flags, lfNoDeepCopy)
assert(a.t != nil)
genLineDir(p, ri)
loadInto(p, e.sons[0], ri, a)
loadInto(p, le, ri, a)
else:
genLineDir(p, e)
asgnFieldDiscriminant(p, e)

View File

@@ -189,3 +189,13 @@ proc nimAsgnStrV2(a: var NimStringV2, b: NimStringV2) {.compilerRtl.} =
a.p.cap = b.len
a.len = b.len
copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1)
proc nimPrepareStrMutationV2(s: var NimStringV2) {.compilerRtl.} =
if s.p != nil and s.p.allocator == nil:
let oldP = s.p
# can't mutate a literal, so we need a fresh copy here:
let allocator = getLocalAllocator()
s.p = cast[ptr NimStrPayload](allocator.alloc(allocator, contentSize(s.len)))
s.p.allocator = allocator
s.p.cap = s.len
copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len+1)

View File

@@ -2,6 +2,7 @@ discard """
cmd: '''nim cpp --newruntime $file'''
output: '''(field: "value")
Indeed
axc
0 new: 0'''
"""
@@ -24,6 +25,11 @@ proc main =
echo w["key"][]
echo getEnv("HEAPTRASHING")
# bug #11891
var x = "abc"
x[1] = 'x'
echo x
main()
# bug #11745