checker: disallow labels in defer statements (#10901)

pull/10936/head
Louis Schmieder 2021-07-23 21:35:05 +02:00 committed by GitHub
parent 69cbdf9fdc
commit 1999850f88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 0 deletions

View File

@ -74,6 +74,7 @@ pub mut:
inside_const bool inside_const bool
inside_anon_fn bool inside_anon_fn bool
inside_ref_lit bool inside_ref_lit bool
inside_defer bool
inside_fn_arg bool // `a`, `b` in `a.f(b)` inside_fn_arg bool // `a`, `b` in `a.f(b)`
inside_ct_attr bool // true inside [if expr] inside_ct_attr bool // true inside [if expr]
skip_flags bool // should `#flag` and `#include` be skipped skip_flags bool // should `#flag` and `#include` be skipped
@ -4486,7 +4487,9 @@ fn (mut c Checker) stmt(node ast.Stmt) {
node.defer_vars[i] = id node.defer_vars[i] = id
} }
} }
c.inside_defer = true
c.stmts(node.stmts) c.stmts(node.stmts)
c.inside_defer = false
} }
ast.EnumDecl { ast.EnumDecl {
c.enum_decl(node) c.enum_decl(node)
@ -4531,6 +4534,9 @@ fn (mut c Checker) stmt(node ast.Stmt) {
} }
ast.GotoLabel {} ast.GotoLabel {}
ast.GotoStmt { ast.GotoStmt {
if c.inside_defer {
c.error('goto is not allowed in defer statements', node.pos)
}
if !c.inside_unsafe { if !c.inside_unsafe {
c.warn('`goto` requires `unsafe` (consider using labelled break/continue)', c.warn('`goto` requires `unsafe` (consider using labelled break/continue)',
node.pos) node.pos)
@ -4593,6 +4599,9 @@ fn (mut c Checker) block(node ast.Block) {
} }
fn (mut c Checker) branch_stmt(node ast.BranchStmt) { fn (mut c Checker) branch_stmt(node ast.BranchStmt) {
if c.inside_defer {
c.error('`$node.kind.str()` is not allowed in defer statements', node.pos)
}
if c.in_for_count == 0 || c.inside_anon_fn { if c.in_for_count == 0 || c.inside_anon_fn {
c.error('$node.kind.str() statement not within a loop', node.pos) c.error('$node.kind.str() statement not within a loop', node.pos)
} }

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/defer_in_for.vv:4:13: error: `break` is not allowed in defer statements
2 | for true {
3 | defer {
4 | break
| ~~~~~
5 | }
6 | }

View File

@ -0,0 +1,7 @@
fn main() {
for true {
defer {
break
}
}
}