From e69d8ec416f9be8004a7ef37a3cf44edf8258585 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 7 Sep 2018 21:06:30 +0200 Subject: Fix type comparison in semConv (#8907) Fixes #8905 --- tests/typerel/t8905.nim | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/typerel/t8905.nim (limited to 'tests') diff --git a/tests/typerel/t8905.nim b/tests/typerel/t8905.nim new file mode 100644 index 000000000..9383962cf --- /dev/null +++ b/tests/typerel/t8905.nim @@ -0,0 +1,7 @@ +type + Foo[T] = distinct seq[T] + Bar[T] = object + +proc newFoo[T](): Foo[T] = Foo[T](newSeq[T]()) + +var x = newFoo[Bar[int]]() -- cgit 1.4.1-2-gfad0 From 91b37311d9974ae30745946a52c9a971da1616f4 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 7 Sep 2018 21:07:06 +0200 Subject: Fix AST generation for case statements (#8908) Fixes #7534 --- compiler/transf.nim | 6 +++++- tests/js/t7534.nim | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/js/t7534.nim (limited to 'tests') diff --git a/compiler/transf.nim b/compiler/transf.nim index 84297aa6a..347df3e49 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -624,7 +624,11 @@ proc transformCase(c: PTransf, n: PNode): PTransNode = case it.kind of nkElifBranch: if ifs.PNode == nil: - ifs = newTransNode(nkIfStmt, it.info, 0) + # Generate the right node depending on whether `n` is used as a stmt or + # as an expr + let kind = if n.typ != nil: nkIfExpr else: nkIfStmt + ifs = newTransNode(kind, it.info, 0) + ifs.PNode.typ = n.typ ifs.add(e) of nkElse: if ifs.PNode == nil: result.add(e) diff --git a/tests/js/t7534.nim b/tests/js/t7534.nim new file mode 100644 index 000000000..64aadb8d6 --- /dev/null +++ b/tests/js/t7534.nim @@ -0,0 +1,7 @@ +proc f(x: int): int = + result = case x + of 1: 2 + elif x == 2: 3 + else: 1 + +doAssert 2 == f(f(f(f(1)))) -- cgit 1.4.1-2-gfad0 From 3f16711254bffaa48dcb9ef0ac1cabc2fad7c5d7 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 8 Sep 2018 10:38:18 +0200 Subject: Fix insert/delete for JS (#8915) Fixes #8914 --- lib/system.nim | 4 ++-- tests/js/t8914.nim | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/js/t8914.nim (limited to 'tests') diff --git a/lib/system.nim b/lib/system.nim index a7e215168..e9ada8c43 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1552,7 +1552,7 @@ proc delete*[T](x: var seq[T], i: Natural) {.noSideEffect.} = defaultImpl() else: when defined(js): - {.emit: "`x`[`x`_Idx].splice(`i`, 1);".} + {.emit: "`x`.splice(`i`, 1);".} else: defaultImpl() @@ -1574,7 +1574,7 @@ proc insert*[T](x: var seq[T], item: T, i = 0.Natural) {.noSideEffect.} = else: when defined(js): var it : T - {.emit: "`x`[`x`_Idx].splice(`i`, 0, `it`);".} + {.emit: "`x`.splice(`i`, 0, `it`);".} else: defaultImpl() x[i] = item diff --git a/tests/js/t8914.nim b/tests/js/t8914.nim new file mode 100644 index 000000000..ff716b42a --- /dev/null +++ b/tests/js/t8914.nim @@ -0,0 +1,12 @@ +discard """ + output: ''' +@[42] +@[24, 42] +''' +""" + +var x = @[42,4242] +x.delete(1) +echo x +x.insert(24) +echo x -- cgit 1.4.1-2-gfad0 From 7107ec05de3a231799dbba66564fb2e22e94217a Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 8 Sep 2018 19:41:07 +0200 Subject: Narrowing casts are applied after every op if needed (#8918) This way we make sure not to end up with weird values every now and then. Fixes #7300 Fixes #8909 --- compiler/semfold.nim | 75 +++++++++++++++++++++++++++++++------------------- tests/arithm/tcast.nim | 43 ++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 32 deletions(-) (limited to 'tests') diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 27a6af1f4..0018f0755 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -214,7 +214,24 @@ proc evalIs(n: PNode, lhs: PSym, g: ModuleGraph): PNode = result = newIntNode(nkIntLit, ord(res)) result.typ = n.typ +proc fitLiteral(c: ConfigRef, n: PNode): PNode = + # Trim the literal value in order to make it fit in the destination type + if n == nil: + # `n` may be nil if the overflow check kicks in + return + + doAssert n.kind in {nkIntLit, nkCharLit} + + result = n + + let typ = n.typ.skipTypes(abstractRange) + if typ.kind in tyUInt..tyUint32: + result.intVal = result.intVal and lastOrd(c, typ, fixedUnsigned=true) + proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = + template doAndFit(op: untyped): untyped = + # Implements wrap-around behaviour for unsigned types + fitLiteral(g.config, op) # b and c may be nil result = nil case m @@ -224,12 +241,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n, g) of mNot: result = newIntNodeT(1 - getInt(a), n, g) of mCard: result = newIntNodeT(nimsets.cardSet(g.config, a), n, g) - of mBitnotI: - case skipTypes(n.typ, abstractRange).kind - of tyUInt..tyUInt64: - result = newIntNodeT((not getInt(a)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g) - else: - result = newIntNodeT(not getInt(a), n, g) + of mBitnotI: result = doAndFit(newIntNodeT(not getInt(a), n, g)) of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g) of mLengthSeq, mLengthOpenArray, mXLenSeq, mLengthStr, mXLenStr: if a.kind == nkNilLit: @@ -251,9 +263,9 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of mToU8: result = newIntNodeT(getInt(a) and 0x000000FF, n, g) of mToU16: result = newIntNodeT(getInt(a) and 0x0000FFFF, n, g) of mToU32: result = newIntNodeT(getInt(a) and 0x00000000FFFFFFFF'i64, n, g) - of mUnaryLt: result = foldSub(getOrdValue(a), 1, n, g) - of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g) - of mPred: result = foldSub(getOrdValue(a), getInt(b), n, g) + of mUnaryLt: result = doAndFit(foldSub(getOrdValue(a), 1, n, g)) + of mSucc: result = doAndFit(foldAdd(getOrdValue(a), getInt(b), n, g)) + of mPred: result = doAndFit(foldSub(getOrdValue(a), getInt(b), n, g)) of mAddI: result = foldAdd(getInt(a), getInt(b), n, g) of mSubI: result = foldSub(getInt(a), getInt(b), n, g) of mMulI: result = foldMul(getInt(a), getInt(b), n, g) @@ -271,7 +283,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of tyInt64, tyInt: result = newIntNodeT(`shl`(getInt(a), getInt(b)), n, g) of tyUInt..tyUInt64: - result = newIntNodeT(`shl`(getInt(a), getInt(b)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g) + result = doAndFit(newIntNodeT(`shl`(getInt(a), getInt(b)), n, g)) else: internalError(g.config, n.info, "constant folding for shl") of mShrI: case skipTypes(n.typ, abstractRange).kind @@ -324,14 +336,14 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = result = newIntNodeT(ord(`<%`(getOrdValue(a), getOrdValue(b))), n, g) of mLeU, mLeU64: result = newIntNodeT(ord(`<=%`(getOrdValue(a), getOrdValue(b))), n, g) - of mBitandI, mAnd: result = newIntNodeT(a.getInt and b.getInt, n, g) - of mBitorI, mOr: result = newIntNodeT(getInt(a) or getInt(b), n, g) - of mBitxorI, mXor: result = newIntNodeT(a.getInt xor b.getInt, n, g) - of mAddU: result = newIntNodeT(`+%`(getInt(a), getInt(b)), n, g) - of mSubU: result = newIntNodeT(`-%`(getInt(a), getInt(b)), n, g) - of mMulU: result = newIntNodeT(`*%`(getInt(a), getInt(b)), n, g) - of mModU: result = foldModU(getInt(a), getInt(b), n, g) - of mDivU: result = foldDivU(getInt(a), getInt(b), n, g) + of mBitandI, mAnd: result = doAndFit(newIntNodeT(a.getInt and b.getInt, n, g)) + of mBitorI, mOr: result = doAndFit(newIntNodeT(getInt(a) or getInt(b), n, g)) + of mBitxorI, mXor: result = doAndFit(newIntNodeT(a.getInt xor b.getInt, n, g)) + of mAddU: result = doAndFit(newIntNodeT(`+%`(getInt(a), getInt(b)), n, g)) + of mSubU: result = doAndFit(newIntNodeT(`-%`(getInt(a), getInt(b)), n, g)) + of mMulU: result = doAndFit(newIntNodeT(`*%`(getInt(a), getInt(b)), n, g)) + of mModU: result = doAndFit(foldModU(getInt(a), getInt(b), n, g)) + of mDivU: result = doAndFit(foldDivU(getInt(a), getInt(b), n, g)) of mLeSet: result = newIntNodeT(ord(containsSets(g.config, a, b)), n, g) of mEqSet: result = newIntNodeT(ord(equalSets(g.config, a, b)), n, g) of mLtSet: @@ -462,17 +474,24 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode = result = newIntNodeT(int(getFloat(a)), n, g) of tyChar: result = newIntNodeT(getOrdValue(a), n, g) - of tyUInt8..tyUInt32, tyInt8..tyInt32: - let fromSigned = srcTyp.kind in tyInt..tyInt64 + of tyUInt..tyUInt64, tyInt..tyInt64: let toSigned = dstTyp.kind in tyInt..tyInt64 - - let mask = lastOrd(g.config, dstTyp, fixedUnsigned=true) - - var val = - if toSigned: - a.getOrdValue mod mask - else: - a.getOrdValue and mask + var val = a.getOrdValue + + if dstTyp.kind in {tyInt, tyInt64, tyUint, tyUInt64}: + # No narrowing needed + discard + elif dstTyp.kind in {tyInt..tyInt64}: + # Signed type: Overflow check (if requested) and conversion + if check: rangeCheck(n, val, g) + let mask = (`shl`(1, getSize(g.config, dstTyp) * 8) - 1) + let valSign = val < 0 + val = abs(val) and mask + if valSign: val = -val + else: + # Unsigned type: Conversion + let mask = (`shl`(1, getSize(g.config, dstTyp) * 8) - 1) + val = val and mask result = newIntNodeT(val, n, g) else: diff --git a/tests/arithm/tcast.nim b/tests/arithm/tcast.nim index 954e2e677..4017ed1c5 100644 --- a/tests/arithm/tcast.nim +++ b/tests/arithm/tcast.nim @@ -4,6 +4,9 @@ B0 B1 B2 B3 +B4 +B5 +B6 ''' """ @@ -14,6 +17,14 @@ template crossCheck(ty: untyped, exp: untyped) = echo "Got ", ct echo "Expected ", rt +template add1(x: uint8): untyped = x + 1 +template add1(x: uint16): untyped = x + 1 +template add1(x: uint32): untyped = x + 1 + +template sub1(x: uint8): untyped = x - 1 +template sub1(x: uint16): untyped = x - 1 +template sub1(x: uint32): untyped = x - 1 + block: when true: echo "B0" @@ -34,10 +45,34 @@ block: crossCheck(uint64, (-1).uint64 + 5'u64) echo "B3" - crossCheck(int8, 0'u8 - 5'u8) - crossCheck(int16, 0'u16 - 5'u16) - crossCheck(int32, 0'u32 - 5'u32) - crossCheck(int64, 0'u64 - 5'u64) + doAssert $sub1(0'u8) == "255" + doAssert $sub1(0'u16) == "65535" + doAssert $sub1(0'u32) == "4294967295" + + echo "B4" + doAssert $add1(255'u8) == "0" + doAssert $add1(65535'u16) == "0" + doAssert $add1(4294967295'u32) == "0" + + echo "B5" + crossCheck(int32, high(int32)) + crossCheck(int32, high(int32).int32) + crossCheck(int32, low(int32)) + crossCheck(int32, low(int32).int32) + crossCheck(int64, high(int8).int16.int32.int64) + crossCheck(int64, low(int8).int16.int32.int64) + + echo "B6" + crossCheck(int64, 0xFFFFFFFFFFFFFFFF'u64) + crossCheck(int32, 0xFFFFFFFFFFFFFFFF'u64) + crossCheck(int16, 0xFFFFFFFFFFFFFFFF'u64) + crossCheck(int8 , 0xFFFFFFFFFFFFFFFF'u64) + + # Out of range conversion, caught for `let`s only + # crossCheck(int8, 0'u8 - 5'u8) + # crossCheck(int16, 0'u16 - 5'u16) + # crossCheck(int32, 0'u32 - 5'u32) + # crossCheck(int64, 0'u64 - 5'u64) # crossCheck(int8, 0'u16 - 129'u16) # crossCheck(uint8, 0'i16 + 257'i16) -- cgit 1.4.1-2-gfad0 From e7d404340628ef2ca6170744a7df33e20cd0fc1a Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 11 Sep 2018 17:03:21 +0200 Subject: Always emit hti object types if needed (#8940) The compiler is now smart enough to emit types only if needed without all the importc tricks. This also fixes a codegen bug where, if all the stars align correctly, typeinfo doesn't include any definition of `TNimType` but uses it. Found by @skilchen in #8938 --- lib/system/hti.nim | 2 +- tests/ccgbugs/thtiobj.nim | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/ccgbugs/thtiobj.nim (limited to 'tests') diff --git a/lib/system/hti.nim b/lib/system/hti.nim index bb3769ac4..9931fa11e 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -11,7 +11,7 @@ when declared(ThisIsSystem): # we are in system module: {.pragma: codegenType, compilerproc.} else: - {.pragma: codegenType, importc.} + {.pragma: codegenType.} type # This should be the same as ast.TTypeKind diff --git a/tests/ccgbugs/thtiobj.nim b/tests/ccgbugs/thtiobj.nim new file mode 100644 index 000000000..7a656905f --- /dev/null +++ b/tests/ccgbugs/thtiobj.nim @@ -0,0 +1,8 @@ +discard """ + targets: "c cpp" +""" + +import typeinfo + +var x = "" +discard (getPointer(toAny(x))) -- cgit 1.4.1-2-gfad0 From de02f5fa0a667dc252fec58aef2a9d177c3b2de5 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 11 Sep 2018 19:14:31 +0200 Subject: add tcollect test for the new for-loops as expressions feature --- tests/macros/tcollect.nim | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/macros/tcollect.nim (limited to 'tests') diff --git a/tests/macros/tcollect.nim b/tests/macros/tcollect.nim new file mode 100644 index 000000000..ae28ab61b --- /dev/null +++ b/tests/macros/tcollect.nim @@ -0,0 +1,63 @@ +discard """ + output: '''@[2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4] +@[0, 1, 2, 3]''' +""" + +const data = [1,2,3,4,5,6] + +import macros + +macro collect(body): untyped = + # analyse the body, find the deepest expression 'it' and replace it via + # 'result.add it' + let res = genSym(nskVar, "collectResult") + + when false: + proc detectForLoopVar(n: NimNode): NimNode = + if n.kind == nnkForStmt: + result = n[0] + else: + for x in n: + result = detectForLoopVar(x) + if result != nil: return result + return nil + + proc t(n, res: NimNode): NimNode = + case n.kind + of nnkStmtList, nnkStmtListExpr, nnkBlockStmt, nnkBlockExpr, + nnkWhileStmt, + nnkForStmt, nnkIfExpr, nnkIfStmt, nnkTryStmt, nnkCaseStmt, + nnkElifBranch, nnkElse, nnkElifExpr: + result = copyNimTree(n) + if n.len >= 1: + result[^1] = t(n[^1], res) + else: + if true: #n == it: + template adder(res, it) = + res.add it + result = getAst adder(res, n) + else: + result = n + + when false: + let it = detectForLoopVar(body) + if it == nil: error("no for loop in body", body) + + let v = newTree(nnkVarSection, + newTree(nnkIdentDefs, res, newTree(nnkBracketExpr, bindSym"seq", + newCall(bindSym"type", body)), newEmptyNode())) + + result = newTree(nnkStmtListExpr, v, t(body, res), res) + #echo repr result + +let stuff = collect: + var i = -1 + while i < 4: + inc i + for it in data: + if it < 5 and it > 1: + it + +echo stuff + +echo collect(for i in 0..3: i) -- cgit 1.4.1-2-gfad0 From 8670f4911b742c87210b97150197080310b5ab58 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 11 Sep 2018 20:32:25 +0200 Subject: Fix semantic pass with borrowed magic procs (#8945) Reported by pqflx3 on the forum. --- compiler/semstmts.nim | 3 +++ tests/ccgbugs/tborrowmagic.nim | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 tests/ccgbugs/tborrowmagic.nim (limited to 'tests') diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index fb01127fc..c2392ec8c 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1173,6 +1173,9 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) = if b != nil: # store the alias: n.sons[bodyPos] = newSymNode(b) + # Carry over the original symbol magic, this is necessary in order to ensure + # the semantic pass is correct + s.magic = b.magic else: localError(c.config, n.info, errNoSymbolToBorrowFromFound) diff --git a/tests/ccgbugs/tborrowmagic.nim b/tests/ccgbugs/tborrowmagic.nim new file mode 100644 index 000000000..8d42ddcd8 --- /dev/null +++ b/tests/ccgbugs/tborrowmagic.nim @@ -0,0 +1,8 @@ +type + Bytes = distinct seq[byte] + +proc add(x: var Bytes; b: byte) {.borrow.} +var x = @[].Bytes +x.add(42) +let base = cast[seq[byte]](x) +doAssert base.len == 1 and base[0] == 42 -- cgit 1.4.1-2-gfad0 From 72170b443d126ffadf35d874cc4d90aa8f843788 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 11 Sep 2018 11:48:45 -0700 Subject: add testcase --- tests/assert/tfailedassert_stacktrace.nim | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/assert/tfailedassert_stacktrace.nim (limited to 'tests') diff --git a/tests/assert/tfailedassert_stacktrace.nim b/tests/assert/tfailedassert_stacktrace.nim new file mode 100644 index 000000000..a3edeb9bf --- /dev/null +++ b/tests/assert/tfailedassert_stacktrace.nim @@ -0,0 +1,19 @@ +discard """ + output: ''' +tfailedassert_stacktrace.nim(16) tfailedassert_stacktrace +tfailedassert_stacktrace.nim(15) foo +system.nim(3777) failedAssertImpl +system.nim(3770) raiseAssert +system.nim(2817) sysFatal +''' +""" + + + +try: + proc foo() = + assert(false) + foo() +except AssertionError: + let e = getCurrentException() + echo e.getStackTrace -- cgit 1.4.1-2-gfad0 From 87955eaf3048bd6b69a988ac330f9d35b2cfa39e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 11 Sep 2018 23:35:21 +0200 Subject: Fix concat behaviour for uninitialized strings (#8950) --- compiler/jsgen.nim | 22 ++++++++++++---------- tests/js/tstrconcat.nim | 5 +++++ 2 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 tests/js/tstrconcat.nim (limited to 'tests') 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" -- cgit 1.4.1-2-gfad0 From b195204549fa99f18fcf1b4d5b757cc5aa7e9a6e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 12 Sep 2018 10:10:00 +0200 Subject: Fix add(string, cstring) when the lhs is null (#8951) --- lib/system.nim | 7 ++++--- tests/js/taddnilstr.nim | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 tests/js/taddnilstr.nim (limited to 'tests') diff --git a/lib/system.nim b/lib/system.nim index a406c7811..4552c6304 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2741,10 +2741,11 @@ type when defined(JS): proc add*(x: var string, y: cstring) {.asmNoStackFrame.} = asm """ - var len = `x`.length; + if (`x` === null) { `x` = []; } + var off = `x`.length; + `x`.length += `y`.length; for (var i = 0; i < `y`.length; ++i) { - `x`[len] = `y`.charCodeAt(i); - ++len; + `x`[off+i] = `y`.charCodeAt(i); } """ proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".} diff --git a/tests/js/taddnilstr.nim b/tests/js/taddnilstr.nim new file mode 100644 index 000000000..f5b934fdd --- /dev/null +++ b/tests/js/taddnilstr.nim @@ -0,0 +1,4 @@ +var x = "foo".cstring +var y: string +add(y, x) +doAssert y == "foo" -- cgit 1.4.1-2-gfad0 From 9b2115558b0146979503a40cb8fbe5722ba262ab Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 12 Sep 2018 12:00:01 -0500 Subject: Test cases for #6969 #7346 #7581 --- tests/seq/t7346.nim | 10 ++++++++++ tests/types/t6969.nim | 10 ++++++++++ tests/types/t7581.nim | 1 + 3 files changed, 21 insertions(+) create mode 100644 tests/seq/t7346.nim create mode 100644 tests/types/t6969.nim create mode 100644 tests/types/t7581.nim (limited to 'tests') diff --git a/tests/seq/t7346.nim b/tests/seq/t7346.nim new file mode 100644 index 000000000..ef2fd5b79 --- /dev/null +++ b/tests/seq/t7346.nim @@ -0,0 +1,10 @@ +when not defined(nimNewRuntime): + {.error: "This bug could only be reproduced with --newruntime".} + +type + Obj = object + a: int + +proc `=`(a: var Obj, b: Obj) = discard + +let a: seq[Obj] = @[] \ No newline at end of file diff --git a/tests/types/t6969.nim b/tests/types/t6969.nim new file mode 100644 index 000000000..d6ce5e62a --- /dev/null +++ b/tests/types/t6969.nim @@ -0,0 +1,10 @@ +discard """ +errormsg: "invalid type: 'object' for var" +line: 6 +""" + +var a: object a: int +# or +var b: ref object a: int +# or +var c: ptr object a: int \ No newline at end of file diff --git a/tests/types/t7581.nim b/tests/types/t7581.nim new file mode 100644 index 000000000..796f30271 --- /dev/null +++ b/tests/types/t7581.nim @@ -0,0 +1 @@ +discard int -1 \ No newline at end of file -- cgit 1.4.1-2-gfad0 From f4356d611585a49de7bce893378c1a997b868005 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 12 Sep 2018 12:58:50 -0500 Subject: Fix system.nim line number test case failure --- tests/assert/tfailedassert_stacktrace.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/assert/tfailedassert_stacktrace.nim b/tests/assert/tfailedassert_stacktrace.nim index a3edeb9bf..43171ef6c 100644 --- a/tests/assert/tfailedassert_stacktrace.nim +++ b/tests/assert/tfailedassert_stacktrace.nim @@ -2,9 +2,9 @@ discard """ output: ''' tfailedassert_stacktrace.nim(16) tfailedassert_stacktrace tfailedassert_stacktrace.nim(15) foo -system.nim(3777) failedAssertImpl -system.nim(3770) raiseAssert -system.nim(2817) sysFatal +system.nim(3778) failedAssertImpl +system.nim(3771) raiseAssert +system.nim(2818) sysFatal ''' """ -- cgit 1.4.1-2-gfad0