summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/sem.nim2
-rw-r--r--compiler/semstmts.nim7
-rw-r--r--compiler/vmgen.nim2
-rw-r--r--tests/casestmt/tcasestmt.nim37
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)