summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-09-11 23:35:21 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-09-11 23:35:21 +0200
commit87955eaf3048bd6b69a988ac330f9d35b2cfa39e (patch)
tree2e5c54a7e452f954cd0d77f5b310bf477201dec3
parent8670f4911b742c87210b97150197080310b5ab58 (diff)
downloadNim-87955eaf3048bd6b69a988ac330f9d35b2cfa39e.tar.gz
Fix concat behaviour for uninitialized strings (#8950)
-rw-r--r--compiler/jsgen.nim22
-rw-r--r--tests/js/tstrconcat.nim5
2 files changed, 17 insertions, 10 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 16ed9dc17..dc0db73b4 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -1660,12 +1660,18 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
     binaryExpr(p, n, r, "addChar",
         "if ($1 != null) { addChar($1, $2); } else { $1 = [$2]; }")
   of mAppendStrStr:
+    var lhs, rhs: TCompRes
+    gen(p, n[1], lhs)
+    gen(p, n[2], rhs)
+
+    let rhsIsLit = n[2].kind in nkStrKinds
     if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
-        binaryExpr(p, n, r, "", "if ($1 != null) { $1 += $2; } else { $1 = $2; }")
+      r.res = "if ($1 != null) { $1 += $2; } else { $1 = $2$3; }" % [
+        lhs.rdLoc, rhs.rdLoc, if rhsIsLit: nil else: ~".slice()"]
     else:
-      binaryExpr(p, n, r, "",
-        "if ($1 != null) { $1 = ($1).concat($2); } else { $1 = $2;}")
-    # XXX: make a copy of $2, because of Javascript's sucking semantics
+      r.res = "if ($1 != null) { $1 = ($1).concat($2); } else { $1 = $2$3; }" % [
+          lhs.rdLoc, rhs.rdLoc, if rhsIsLit: nil else: ~".slice()"]
+    r.kind = resExpr
   of mAppendSeqElem:
     var x, y: TCompRes
     gen(p, n.sons[1], x)
@@ -1693,13 +1699,9 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
   of mSizeOf: r.res = rope(getSize(p.config, n.sons[1].typ))
   of mChr, mArrToSeq: gen(p, n.sons[1], r)      # nothing to do
   of mOrd: genOrd(p, n, r)
-  of mLengthStr:
-    unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)")
-  of mXLenStr:
-    unaryExpr(p, n, r, "", "$1.length")
-  of mLengthSeq, mLengthOpenArray, mLengthArray:
+  of mLengthStr, mLengthSeq, mLengthOpenArray, mLengthArray:
     unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)")
-  of mXLenSeq:
+  of mXLenStr, mXLenSeq:
     unaryExpr(p, n, r, "", "$1.length")
   of mHigh:
     unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)")
diff --git a/tests/js/tstrconcat.nim b/tests/js/tstrconcat.nim
new file mode 100644
index 000000000..37c8db687
--- /dev/null
+++ b/tests/js/tstrconcat.nim
@@ -0,0 +1,5 @@
+var x: string
+var y = "foo"
+add(x, y)
+y[0] = 'm'
+doAssert y == "moo" and x == "foo"