summary refs log tree commit diff stats
path: root/compiler/semstmts.nim
diff options
context:
space:
mode:
authorDheepak Krishnamurthy <kdheepak89@gmail.com>2018-10-09 06:09:22 -0600
committerAndreas Rumpf <rumpf_a@web.de>2018-10-09 14:09:22 +0200
commit70018aa683f93998b1b263cb0ddb5ec13ee4cfdf (patch)
treeff5e2b6e8c2a3707ff7784ec8e07333601ecceae /compiler/semstmts.nim
parentdd659867955d87affde0b6271cc9bf86208462dc (diff)
downloadNim-70018aa683f93998b1b263cb0ddb5ec13ee4cfdf.tar.gz
Add checks for except: body blocks (#9191)
Diffstat (limited to 'compiler/semstmts.nim')
-rw-r--r--compiler/semstmts.nim21
1 files changed, 20 insertions, 1 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index f2cb2dcb3..2817b5ef9 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -207,6 +207,8 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode =
   typ = commonType(typ, n[0].typ)
 
   var last = sonsLen(n) - 1
+  var catchAllExcepts = 0
+
   for i in countup(1, last):
     let a = n.sons[i]
     checkMinSonsLen(a, 1, c.config)
@@ -227,8 +229,16 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode =
         # Overwrite symbol in AST with the symbol in the symbol table.
         a[0][2] = newSymNode(symbol, a[0][2].info)
 
+      elif a.len == 1:
+          # count number of ``except: body`` blocks
+          inc catchAllExcepts
+
       else:
         # support ``except KeyError, ValueError, ... : body``
+        if catchAllExcepts > 0:
+          # if ``except: body`` already encountered,
+          # cannot be followed by a ``except KeyError, ... : body`` block
+          inc catchAllExcepts
         var is_native, is_imported: bool
         for j in 0..a.len-2:
           let tmp = semExceptBranchType(a[j])
@@ -238,9 +248,18 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode =
         if is_native and is_imported:
           localError(c.config, a[0].info, "Mix of imported and native exception types is not allowed in one except branch")
 
-    elif a.kind != nkFinally:
+    elif a.kind == nkFinally:
+      if i != n.len-1:
+        localError(c.config, a.info, "Only one finally is allowed after all other branches")
+
+    else:
       illFormedAst(n, c.config)
 
+    if catchAllExcepts > 1:
+      # if number of ``except: body`` blocks is greater than 1
+      # or more specific exception follows a general except block, it is invalid
+      localError(c.config, a.info, "Only one general except clause is allowed after more specific exceptions")
+
     # last child of an nkExcept/nkFinally branch is a statement:
     a[^1] = semExprBranchScope(c, a[^1])
     if a.kind != nkFinally: typ = commonType(typ, a[^1])