mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
Add checks for except: body blocks (#9191)
This commit is contained in:
committed by
Andreas Rumpf
parent
dd65986795
commit
70018aa683
@@ -1578,7 +1578,6 @@ proc parseTry(p: var TParser; isExpr: bool): PNode =
|
||||
colcom(p, b)
|
||||
addSon(b, parseStmt(p))
|
||||
addSon(result, b)
|
||||
if b.kind == nkFinally: break
|
||||
if b == nil: parMessage(p, "expected 'except'")
|
||||
|
||||
proc parseExceptBlock(p: var TParser, kind: TNodeKind): PNode =
|
||||
|
||||
@@ -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])
|
||||
|
||||
10
tests/errmsgs/tgeneral_excepts.nim
Normal file
10
tests/errmsgs/tgeneral_excepts.nim
Normal file
@@ -0,0 +1,10 @@
|
||||
discard """
|
||||
errormsg: "Only one general except clause is allowed after more specific exceptions"
|
||||
"""
|
||||
|
||||
try:
|
||||
discard
|
||||
except:
|
||||
discard
|
||||
except:
|
||||
discard
|
||||
12
tests/errmsgs/tmultiple_finally.nim
Normal file
12
tests/errmsgs/tmultiple_finally.nim
Normal file
@@ -0,0 +1,12 @@
|
||||
discard """
|
||||
errormsg: "Only one finally is allowed after all other branches"
|
||||
"""
|
||||
|
||||
try:
|
||||
discard
|
||||
finally:
|
||||
discard
|
||||
finally:
|
||||
discard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user