diff options
-rw-r--r-- | compiler/ccgexprs.nim | 1 | ||||
-rw-r--r-- | compiler/jsgen.nim | 11 | ||||
-rw-r--r-- | tests/js/taddr.nim | 62 |
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] |