mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 15:31:28 +00:00
fixes #11891
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user