summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2020-07-25 20:26:30 +0200
committerAndreas Rumpf <rumpf_a@web.de>2020-07-26 01:16:06 +0200
commit624762cfb7ab17606616f75ca280b83c55c3ec3b (patch)
treee2f2b511501baafd3a581fecde337ed297568617
parent5c4e2bf68e067507ce0f26c93737b302bbeb5103 (diff)
downloadNim-624762cfb7ab17606616f75ca280b83c55c3ec3b.tar.gz
fixes #15052
-rw-r--r--compiler/ccgexprs.nim11
-rw-r--r--tests/arc/tarcmisc.nim11
2 files changed, 22 insertions, 0 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 003b3e240..73cc2c8a1 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -729,6 +729,15 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc) =
     else:
       putIntoDest(p, d, e, "(*$1)" % [rdLoc(a)], a.storage)
 
+proc cow(p: BProc; n: PNode) =
+  if n.kind == nkHiddenAddr and optSeqDestructors in p.config.globalOptions:
+    if n[0].kind == nkBracketExpr:
+      let strCandidate = n[0][0]
+      if strCandidate.typ.skipTypes(abstractInst).kind == tyString:
+        var a: TLoc
+        initLocExpr(p, strCandidate, a)
+        linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
+
 proc genAddr(p: BProc, e: PNode, d: var TLoc) =
   # careful  'addr(myptrToArray)' needs to get the ampersand:
   if e[0].typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr}:
@@ -2699,9 +2708,11 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
   of nkReturnStmt: genReturnStmt(p, n)
   of nkBreakStmt: genBreakStmt(p, n)
   of nkAsgn:
+    cow(p, n[1])
     if nfPreventCg notin n.flags:
       genAsgn(p, n, fastAsgn=false)
   of nkFastAsgn:
+    cow(p, n[1])
     if nfPreventCg notin n.flags:
       # transf is overly aggressive with 'nkFastAsgn', so we work around here.
       # See tests/run/tcnstseq3 for an example that would fail otherwise.
diff --git a/tests/arc/tarcmisc.nim b/tests/arc/tarcmisc.nim
index cb889db15..d60e932a8 100644
--- a/tests/arc/tarcmisc.nim
+++ b/tests/arc/tarcmisc.nim
@@ -24,6 +24,7 @@ whiley ends :(
 new line before - @['a']
 new line after - @['a']
 finalizer
+aaaaa
 closed
 destroying variable: 20
 destroying variable: 10
@@ -282,3 +283,13 @@ proc hello(): int =
 
 var leaves {.global.} = hello()
 doAssert leaves == 42
+
+# bug #15052
+
+proc mutstrings =
+  var data = "hello"
+  for c in data.mitems():
+    c = 'a'
+  echo data
+
+mutstrings()