checker: unreachable code warning

pull/4645/head
Henrixounez 2020-04-29 12:31:18 +02:00 committed by GitHub
parent 2fc05b814c
commit c500044bae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 0 deletions

View File

@ -852,3 +852,79 @@ fn (expr Expr) position() token.Position {
}
}
}
fn (stmt Stmt) position() token.Position {
match mut stmt {
AssertStmt {
return it.pos
}
AssignStmt {
return it.pos
}
// Attr {
// }
// Block {
// }
// BranchStmt {
// }
Comment {
return it.pos
}
CompIf {
return it.pos
}
ConstDecl {
return it.pos
}
// DeferStmt {
// }
EnumDecl {
return it.pos
}
ExprStmt {
return it.pos
}
FnDecl {
return it.pos
}
ForCStmt {
return it.pos
}
ForInStmt {
return it.pos
}
ForStmt {
return it.pos
}
// GlobalDecl {
// }
// GoStmt {
// }
// GotoLabel {
// }
// GotoStmt {
// }
// HashStmt {
// }
Import {
return it.pos
}
// InterfaceDecl {
// }
// Module {
// }
Return {
return it.pos
}
StructDecl {
return it.pos
}
// TypeDecl {
// }
// UnsafeStmt {
// }
else {
return token.Position{}
}
}
}

View File

@ -34,6 +34,7 @@ mut:
// checked_ident string // to avoid infinit checker loops
var_decl_name string
returns bool
scope_returns bool
mod string // current module name
is_builtin_mod bool // are we in `builtin`?
}
@ -1398,6 +1399,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
ast.Return {
c.returns = true
c.return_stmt(mut it)
c.scope_returns = true
}
ast.StructDecl {
c.struct_decl(it)
@ -1416,10 +1418,20 @@ fn (mut c Checker) stmt(node ast.Stmt) {
}
fn (mut c Checker) stmts(stmts []ast.Stmt) {
mut unreachable := token.Position{line_nr: -1}
c.expected_type = table.void_type
for stmt in stmts {
if c.scope_returns {
if unreachable.line_nr == -1 {
unreachable = stmt.position()
}
}
c.stmt(stmt)
}
if unreachable.line_nr >= 0 {
c.warn('unreachable code', unreachable)
}
c.scope_returns = false
c.expected_type = table.void_type
}

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/unreachable_code.v:3:7: error: unreachable code
1| fn foo() int {
2| return if 1 == 1 { 1 } else { 2 }
3| a := 1
^
4| println(a)
5| }

View File

@ -0,0 +1,8 @@
fn foo() int {
return if 1 == 1 { 1 } else { 2 }
a := 1
println(a)
}
fn main() {
foo()
}