summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-08-10 15:41:24 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-08-10 15:41:24 +0200
commit212ae2f1257628bd5d1760593ce0a1bad768831a (patch)
treeb66050091e82c2d891bb18f97ebc812eb34cf416 /compiler
parent0e4a8bfb289d707909069e72ca24efd2a074a5f1 (diff)
downloadNim-212ae2f1257628bd5d1760593ce0a1bad768831a.tar.gz
fixes #11891
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/ccgexprs.nim4
-rw-r--r--compiler/ccgstmts.nim4
3 files changed, 10 insertions, 2 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 6238acb14..48e8afa67 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -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
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index a9932a0ce..224054506 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -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)
 
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index bf07c1af7..337b36904 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -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)