summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgexprs.nim1
-rw-r--r--compiler/jsgen.nim11
-rw-r--r--tests/js/taddr.nim62
3 files changed, 71 insertions, 3 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index ec54081a2..2850ab750 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -141,6 +141,7 @@ proc genSetNode(p: BProc, n: PNode): Rope =
     result = genRawSetData(cs, size)
 
 proc getStorageLoc(n: PNode): TStorageLoc =
+  ## deadcode
   case n.kind
   of nkSym:
     case n.sym.kind
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 0410a7a55..9f022882b 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -1065,8 +1065,11 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
         lineF(p, "var $1 = $4; $2 = $1[0]; $3 = $1[1];$n", [tmp, a.address, a.res, b.rdLoc])
       elif b.typ == etyBaseIndex:
         lineF(p, "$# = [$#, $#];$n", [a.res, b.address, b.res])
+      elif b.typ == etyNone:
+        internalAssert p.config, b.address == nil
+        lineF(p, "$# = [$#, 0];$n", [a.address, b.res])
       else:
-        internalError(p.config, x.info, "genAsgn")
+        internalError(p.config, x.info, $("genAsgn", b.typ, a.typ))
     else:
       lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
   else:
@@ -1266,6 +1269,10 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
     let s = n[0].sym
     if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
     case s.kind
+    of skParam:
+      r.res = s.loc.r
+      r.address = nil
+      r.typ = etyNone
     of skVar, skLet, skResult:
       r.kind = resExpr
       let jsType = mapType(p, n.typ)
@@ -1287,7 +1294,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
         # 'var openArray' for instance produces an 'addr' but this is harmless:
         gen(p, n[0], r)
         #internalError(p.config, n.info, "genAddr: 4 " & renderTree(n))
-    else: internalError(p.config, n.info, "genAddr: 2")
+    else: internalError(p.config, n.info, $("genAddr: 2", s.kind))
   of nkCheckedFieldExpr:
     genCheckedFieldOp(p, n[0], n.typ, r)
   of nkDotExpr:
diff --git a/tests/js/taddr.nim b/tests/js/taddr.nim
index d8ff4c11b..9c45621a8 100644
--- a/tests/js/taddr.nim
+++ b/tests/js/taddr.nim
@@ -1,5 +1,5 @@
 discard """
-  action: run
+  targets: "c js"
 """
 
 type T = object
@@ -77,3 +77,63 @@ let someGlobalPtr = getSomeGlobalPtr()
 doAssert(someGlobalPtr[] == 5)
 someGlobalPtr[] = 10
 doAssert(someGlobal == 10)
+
+block:
+  # issue #14576
+  # lots of these used to give: Error: internal error: genAddr: 2
+  proc byLent[T](a: T): lent T = a
+  proc byPtr[T](a: T): ptr T = a.unsafeAddr
+
+  block:
+    let a = (10,11)
+    let (x,y) = byLent(a)
+    doAssert (x,y) == a
+
+  block:
+    when defined(c) and defined(release):
+      # bug; pending https://github.com/nim-lang/Nim/issues/14578
+      discard
+    else:
+      let a = 10
+      doAssert byLent(a) == 10
+      let a2 = byLent(a)
+      doAssert a2 == 10
+
+  block:
+    let a = [11,12]
+    doAssert byLent(a) == [11,12]
+    let a2 = (11,)
+    doAssert byLent(a2) == (11,)
+
+  block:
+    when defined(c) and defined(release):
+      discard # probably not a bug since optimizer is free to pass by value, and `unsafeAddr` is used
+    else:
+      var a = @[12]
+      doAssert byPtr(a)[] == @[12]
+      let a2 = [13]
+      doAssert byPtr(a2)[] == [13]
+      let a3 = 14
+      doAssert byPtr(a3)[] == 14
+
+  block:
+    proc byLent2[T](a: seq[T]): lent T = a[1]
+    var a = @[20,21,22]
+    doAssert byLent2(a) == 21
+
+  block: # sanity checks
+    proc bar[T](a: var T): var T = a
+    var a = (10, 11)
+    let (k,v) = bar(a)
+    doAssert (k, v) == a
+    doAssert k == 10
+    bar(a)[0]+=100
+    doAssert a == (110, 11)
+    var a2 = 12
+    doAssert bar(a2) == a2
+    bar(a2).inc
+    doAssert a2 == 13
+
+  block: # xxx: bug this doesn't work
+    when false:
+      proc byLent2[T](a: T): lent type(a[0]) = a[0]