fixes #11891
This commit is contained in:
parent
0e4a8bfb28
commit
212ae2f125
5 changed files with 26 additions and 2 deletions
|
|
@ -759,7 +759,9 @@ type
|
||||||
lfImportCompilerProc, # ``importc`` of a compilerproc
|
lfImportCompilerProc, # ``importc`` of a compilerproc
|
||||||
lfSingleUse # no location yet and will only be used once
|
lfSingleUse # no location yet and will only be used once
|
||||||
lfEnforceDeref # a copyMem is required to dereference if this a
|
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
|
TStorageLoc* = enum
|
||||||
OnUnknown, # location is unknown (stack, heap or static)
|
OnUnknown, # location is unknown (stack, heap or static)
|
||||||
OnStatic, # in a static section
|
OnStatic, # in a static section
|
||||||
|
|
|
||||||
|
|
@ -944,6 +944,10 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
if d.k == locNone: d.storage = OnHeap
|
if d.k == locNone: d.storage = OnHeap
|
||||||
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
||||||
a.r = ropecg(p.module, "(*$1)", [a.r])
|
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,
|
putIntoDest(p, d, n,
|
||||||
ropecg(p.module, "$1$3[$2]", [rdLoc(a), rdCharLoc(b), dataField(p)]), a.storage)
|
ropecg(p.module, "$1$3[$2]", [rdLoc(a), rdCharLoc(b), dataField(p)]), a.storage)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1266,11 +1266,13 @@ proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
|
||||||
discard getTypeDesc(p.module, le.typ.skipTypes(skipPtrs))
|
discard getTypeDesc(p.module, le.typ.skipTypes(skipPtrs))
|
||||||
initLoc(a, locNone, le, OnUnknown)
|
initLoc(a, locNone, le, OnUnknown)
|
||||||
a.flags.incl(lfEnforceDeref)
|
a.flags.incl(lfEnforceDeref)
|
||||||
|
a.flags.incl(lfPrepareForMutation)
|
||||||
expr(p, le, a)
|
expr(p, le, a)
|
||||||
|
a.flags.excl(lfPrepareForMutation)
|
||||||
if fastAsgn: incl(a.flags, lfNoDeepCopy)
|
if fastAsgn: incl(a.flags, lfNoDeepCopy)
|
||||||
assert(a.t != nil)
|
assert(a.t != nil)
|
||||||
genLineDir(p, ri)
|
genLineDir(p, ri)
|
||||||
loadInto(p, e.sons[0], ri, a)
|
loadInto(p, le, ri, a)
|
||||||
else:
|
else:
|
||||||
genLineDir(p, e)
|
genLineDir(p, e)
|
||||||
asgnFieldDiscriminant(p, e)
|
asgnFieldDiscriminant(p, e)
|
||||||
|
|
|
||||||
|
|
@ -189,3 +189,13 @@ proc nimAsgnStrV2(a: var NimStringV2, b: NimStringV2) {.compilerRtl.} =
|
||||||
a.p.cap = b.len
|
a.p.cap = b.len
|
||||||
a.len = b.len
|
a.len = b.len
|
||||||
copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1)
|
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)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ discard """
|
||||||
cmd: '''nim cpp --newruntime $file'''
|
cmd: '''nim cpp --newruntime $file'''
|
||||||
output: '''(field: "value")
|
output: '''(field: "value")
|
||||||
Indeed
|
Indeed
|
||||||
|
axc
|
||||||
0 new: 0'''
|
0 new: 0'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -24,6 +25,11 @@ proc main =
|
||||||
echo w["key"][]
|
echo w["key"][]
|
||||||
echo getEnv("HEAPTRASHING")
|
echo getEnv("HEAPTRASHING")
|
||||||
|
|
||||||
|
# bug #11891
|
||||||
|
var x = "abc"
|
||||||
|
x[1] = 'x'
|
||||||
|
echo x
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
# bug #11745
|
# bug #11745
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue