checker: make sure functions return

pull/4358/head
Alexander Medvednikov 2020-04-11 21:50:14 +02:00
parent 581d836de6
commit 449d839684
2 changed files with 12 additions and 1 deletions

View File

@ -32,6 +32,7 @@ mut:
in_for_count int // if checker is currently in an for loop
// checked_ident string // to avoid infinit checker loops
var_decl_name string
returns bool
}
pub fn new_checker(table &table.Table, pref &pref.Preferences) Checker {
@ -250,6 +251,9 @@ fn (c mut Checker) assign_expr(assign_expr mut ast.AssignExpr) {
}
pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
if call_expr.name == 'panic' {
c.returns = true
}
c.stmts(call_expr.or_block.stmts)
if call_expr.is_method {
left_type := c.expr(call_expr.left)
@ -876,6 +880,11 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.expected_type = table.void_type
c.fn_return_type = it.return_type
c.stmts(it.stmts)
if !it.is_c && !it.no_body && it.return_type != table.void_type && !c.returns &&
!(it.name in ['panic', 'exit']) {
c.error('missing return at end of function `$it.name`', it.pos)
}
c.returns = false
}
ast.ForStmt {
c.in_for_count++
@ -937,6 +946,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
ast.Import {}
// ast.GlobalDecl {}
ast.Return {
c.returns = true
c.return_stmt(mut it)
}
// ast.StructDecl {}

View File

@ -83,6 +83,7 @@ pub fn (p mut Parser) call_args() []ast.CallArg {
fn (p mut Parser) fn_decl() ast.FnDecl {
// p.table.clear_vars()
pos := p.tok.position()
p.open_scope()
is_deprecated := p.attr == 'deprecated'
is_pub := p.tok.kind == .key_pub
@ -207,7 +208,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
rec_mut: rec_mut
is_c: is_c
no_body: no_body
pos: p.tok.position()
pos: pos
is_builtin: p.builtin_mod || p.mod in ['math', 'strconv', 'strconv.ftoa', 'hash.wyhash',
'math.bits', 'strings']
}