diff options
-rw-r--r-- | compiler/ccgstmts.nim | 35 | ||||
-rw-r--r-- | tests/ccgbugs/tbug1081.nim | 19 |
2 files changed, 49 insertions, 5 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 5434d87b2..8fb096c70 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1112,19 +1112,46 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) = genDiscriminantCheck(p, a, tmp, dotExpr.sons[0].typ, dotExpr.sons[1].sym) genAssignment(p, a, tmp, {}) +proc patchAsgnStmtListExpr(father, orig, n: PNode) = + case n.kind + of nkDerefExpr, nkHiddenDeref: + let asgn = copyNode(orig) + asgn.add orig[0] + asgn.add n + father.add asgn + of nkStmtList, nkStmtListExpr: + for x in n: + patchAsgnStmtListExpr(father, orig, x) + else: + father.add n + proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) = if e.sons[0].kind == nkSym and sfGoto in e.sons[0].sym.flags: genLineDir(p, e) genGotoVar(p, e.sons[1]) elif not fieldDiscriminantCheckNeeded(p, e): + # this fixes bug #6422 but we really need to change the representation of + # arrays in the backend... + let le = e[0] + let ri = e[1] + var needsRepair = false + var it = ri + while it.kind in {nkStmtList, nkStmtListExpr}: + it = it.lastSon + needsRepair = true + if it.kind in {nkDerefExpr, nkHiddenDeref} and needsRepair: + var patchedTree = newNodeI(nkStmtList, e.info) + patchAsgnStmtListExpr(patchedTree, e, ri) + genStmts(p, patchedTree) + return + var a: TLoc - if e[0].kind in {nkDerefExpr, nkHiddenDeref}: - genDeref(p, e[0], a, enforceDeref=true) + if le.kind in {nkDerefExpr, nkHiddenDeref}: + genDeref(p, le, a, enforceDeref=true) else: - initLocExpr(p, e.sons[0], a) + initLocExpr(p, le, a) if fastAsgn: incl(a.flags, lfNoDeepCopy) assert(a.t != nil) - let ri = e.sons[1] genLineDir(p, ri) loadInto(p, e.sons[0], ri, a) else: diff --git a/tests/ccgbugs/tbug1081.nim b/tests/ccgbugs/tbug1081.nim index 71628feec..c9a9e6aa4 100644 --- a/tests/ccgbugs/tbug1081.nim +++ b/tests/ccgbugs/tbug1081.nim @@ -2,7 +2,8 @@ discard """ output: '''1 0 0 -0''' +0 +x = [a, b, c, 0, 1, 2, 3, 4, 5, 6] and y = [a, b, c, 0, 1, 2, 3, 4, 5, 6]''' """ proc `1/1`() = echo(1 div 1) @@ -15,3 +16,19 @@ let `1/4` = 1 div 4 `1/2`() echo `1/3` echo `1/4` + +# bug #6422 + +proc toCharArray1(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + x[] + +proc toCharArray2(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + result = x[] + +let x = toCharArray1(10, "abc0123456") +let y = toCharArray2(10, "abc0123456") +echo "x = ", $x, " and y = ", $y |