Add checks for except: body blocks (#9191)
This commit is contained in:
parent
dd65986795
commit
70018aa683
4 changed files with 42 additions and 2 deletions
|
|
@ -1578,7 +1578,6 @@ proc parseTry(p: var TParser; isExpr: bool): PNode =
|
||||||
colcom(p, b)
|
colcom(p, b)
|
||||||
addSon(b, parseStmt(p))
|
addSon(b, parseStmt(p))
|
||||||
addSon(result, b)
|
addSon(result, b)
|
||||||
if b.kind == nkFinally: break
|
|
||||||
if b == nil: parMessage(p, "expected 'except'")
|
if b == nil: parMessage(p, "expected 'except'")
|
||||||
|
|
||||||
proc parseExceptBlock(p: var TParser, kind: TNodeKind): PNode =
|
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)
|
typ = commonType(typ, n[0].typ)
|
||||||
|
|
||||||
var last = sonsLen(n) - 1
|
var last = sonsLen(n) - 1
|
||||||
|
var catchAllExcepts = 0
|
||||||
|
|
||||||
for i in countup(1, last):
|
for i in countup(1, last):
|
||||||
let a = n.sons[i]
|
let a = n.sons[i]
|
||||||
checkMinSonsLen(a, 1, c.config)
|
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.
|
# Overwrite symbol in AST with the symbol in the symbol table.
|
||||||
a[0][2] = newSymNode(symbol, a[0][2].info)
|
a[0][2] = newSymNode(symbol, a[0][2].info)
|
||||||
|
|
||||||
|
elif a.len == 1:
|
||||||
|
# count number of ``except: body`` blocks
|
||||||
|
inc catchAllExcepts
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# support ``except KeyError, ValueError, ... : body``
|
# 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
|
var is_native, is_imported: bool
|
||||||
for j in 0..a.len-2:
|
for j in 0..a.len-2:
|
||||||
let tmp = semExceptBranchType(a[j])
|
let tmp = semExceptBranchType(a[j])
|
||||||
|
|
@ -238,9 +248,18 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
||||||
if is_native and is_imported:
|
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")
|
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)
|
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:
|
# last child of an nkExcept/nkFinally branch is a statement:
|
||||||
a[^1] = semExprBranchScope(c, a[^1])
|
a[^1] = semExprBranchScope(c, a[^1])
|
||||||
if a.kind != nkFinally: typ = commonType(typ, 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
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue