mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check for unused labels
This commit is contained in:
parent
af41058979
commit
4d3401c852
@ -125,6 +125,7 @@ mut:
|
||||
inside_decl_rhs bool
|
||||
inside_if_guard bool // true inside the guard condition of `if x := opt() {}`
|
||||
comptime_call_pos int // needed for correctly checking use before decl for templates
|
||||
goto_labels map[string]int // to check for unused goto labels
|
||||
}
|
||||
|
||||
pub fn new_checker(table &ast.Table, pref &pref.Preferences) &Checker {
|
||||
@ -226,6 +227,7 @@ pub fn (mut c Checker) check(ast_file_ &ast.File) {
|
||||
}
|
||||
|
||||
c.check_scope_vars(c.file.scope)
|
||||
c.check_unused_labels()
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
|
||||
@ -1562,19 +1564,11 @@ fn (mut c Checker) stmt(node_ ast.Stmt) {
|
||||
ast.GlobalDecl {
|
||||
c.global_decl(mut node)
|
||||
}
|
||||
ast.GotoLabel {}
|
||||
ast.GotoLabel {
|
||||
c.goto_label(node)
|
||||
}
|
||||
ast.GotoStmt {
|
||||
if c.inside_defer {
|
||||
c.error('goto is not allowed in defer statements', node.pos)
|
||||
}
|
||||
if !c.inside_unsafe {
|
||||
c.warn('`goto` requires `unsafe` (consider using labelled break/continue)',
|
||||
node.pos)
|
||||
}
|
||||
if !isnil(c.table.cur_fn) && node.name !in c.table.cur_fn.label_names {
|
||||
c.error('unknown label `$node.name`', node.pos)
|
||||
}
|
||||
// TODO: check label doesn't bypass variable declarations
|
||||
c.goto_stmt(node)
|
||||
}
|
||||
ast.HashStmt {
|
||||
c.hash_stmt(mut node)
|
||||
@ -3895,6 +3889,36 @@ pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what stri
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) goto_label(node ast.GotoLabel) {
|
||||
// Register a goto label
|
||||
if c.goto_labels[node.name] == 0 {
|
||||
c.goto_labels[node.name] = 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) goto_stmt(node ast.GotoStmt) {
|
||||
if c.inside_defer {
|
||||
c.error('goto is not allowed in defer statements', node.pos)
|
||||
}
|
||||
if !c.inside_unsafe {
|
||||
c.warn('`goto` requires `unsafe` (consider using labelled break/continue)', node.pos)
|
||||
}
|
||||
if !isnil(c.table.cur_fn) && node.name !in c.table.cur_fn.label_names {
|
||||
c.error('unknown label `$node.name`', node.pos)
|
||||
}
|
||||
c.goto_labels[node.name]++ // Register a label use
|
||||
// TODO: check label doesn't bypass variable declarations
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_unused_labels() {
|
||||
for label, nr_uses in c.goto_labels {
|
||||
if nr_uses == 0 {
|
||||
// TODO show label's location
|
||||
c.warn('label `$label` defined and not used', token.Pos{})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) deprecate(kind string, name string, attrs []ast.Attr, pos token.Pos) {
|
||||
mut deprecation_message := ''
|
||||
now := time.now()
|
||||
|
5
vlib/v/checker/tests/unused_label.out
Normal file
5
vlib/v/checker/tests/unused_label.out
Normal file
@ -0,0 +1,5 @@
|
||||
vlib/v/checker/tests/unused_label.vv:1:1: warning: label `mylabel` defined and not used
|
||||
1 | fn main() {
|
||||
| ^
|
||||
2 | mylabel:
|
||||
3 | }
|
3
vlib/v/checker/tests/unused_label.vv
Normal file
3
vlib/v/checker/tests/unused_label.vv
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
mylabel:
|
||||
}
|
Loading…
Reference in New Issue
Block a user