diff options
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/sem.nim | 2 | ||||
-rw-r--r-- | compiler/semstmts.nim | 7 | ||||
-rw-r--r-- | compiler/vmgen.nim | 2 | ||||
-rw-r--r-- | tests/casestmt/tcasestmt.nim | 37 |
5 files changed, 42 insertions, 8 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 5938d4e53..70c14ccaf 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -336,6 +336,8 @@ const tagEffects* = 3 # user defined tag ('gc', 'time' etc.) pragmasEffects* = 4 # not an effect, but a slot for pragmas in proc type effectListLen* = 5 # list of effects list + nkLastBlockStmts* = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} + # these must be last statements in a block type TTypeKind* = enum # order is important! diff --git a/compiler/sem.nim b/compiler/sem.nim index 831e16017..48f767af7 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -181,7 +181,7 @@ proc endsInNoReturn(n: PNode): bool = var it = n while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0: it = it.lastSon - result = it.kind == nkRaiseStmt or + result = it.kind in nkLastBlockStmts or it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags proc commonType*(x: PType, y: PNode): PType = diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 7636705e0..deffe563c 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -120,7 +120,7 @@ const proc implicitlyDiscardable(n: PNode): bool = var n = n while n.kind in skipForDiscardable: n = n.lastSon - result = n.kind == nkRaiseStmt or + result = n.kind in nkLastBlockStmts or (isCallExpr(n) and n[0].kind == nkSym and sfDiscardable in n[0].sym.flags) @@ -2162,9 +2162,6 @@ proc inferConceptStaticParam(c: PContext, inferred, n: PNode) = typ.n = res proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = - # these must be last statements in a block: - const - LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} result = n result.transitionSonsKind(nkStmtList) var voidContext = false @@ -2209,7 +2206,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = else: n.typ = n[i].typ if not isEmptyType(n.typ): n.transitionSonsKind(nkStmtListExpr) - if n[i].kind in LastBlockStmts or + if n[i].kind in nkLastBlockStmts or n[i].kind in nkCallKinds and n[i][0].kind == nkSym and sfNoReturn in n[i][0].sym.flags: for j in i + 1..<n.len: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index a34ef5d09..0b8eafd17 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -2094,12 +2094,10 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = genWhile(c, n) of nkBlockExpr, nkBlockStmt: genBlock(c, n, dest) of nkReturnStmt: - unused(c, n, dest) genReturn(c, n) of nkRaiseStmt: genRaise(c, n) of nkBreakStmt: - unused(c, n, dest) genBreak(c, n) of nkTryStmt, nkHiddenTryStmt: genTry(c, n, dest) of nkStmtList: diff --git a/tests/casestmt/tcasestmt.nim b/tests/casestmt/tcasestmt.nim index b7454ef99..6abea53bc 100644 --- a/tests/casestmt/tcasestmt.nim +++ b/tests/casestmt/tcasestmt.nim @@ -250,3 +250,40 @@ proc negativeOrNot(num: int): string = doAssert negativeOrNot(-1) == "negative" doAssert negativeOrNot(10000000) == "zero or positive" doAssert negativeOrNot(0) == "zero or positive" + +######################################################## +# issue #13490 +import strutils +func foo(input: string): int = + try: + parseInt(input) + except: + return + +func foo2(b, input: string): int = + case b: + of "Y": + for c in input: + result = if c in '0'..'9': parseInt($c) + else: break + of "N": + for c in input: + result = if c in '0'..'9': parseInt($c) + else: continue + else: return + + +static: + doAssert(foo("3") == 3) + doAssert(foo("a") == 0) + doAssert(foo2("Y", "a2") == 0) + doAssert(foo2("Y", "2a") == 2) + doAssert(foo2("N", "a3") == 3) + doAssert(foo2("z", "2") == 0) + +doAssert(foo("3") == 3) +doAssert(foo("a") == 0) +doAssert(foo2("Y", "a2") == 0) +doAssert(foo2("Y", "2a") == 2) +doAssert(foo2("N", "a3") == 3) +doAssert(foo2("z", "2") == 0) |