From 1b6cccaf6d02c009908de39fc6d09e2387fc8136 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Thu, 28 Oct 2021 10:40:18 +0300 Subject: [PATCH] parser,checker: allow a goto label right after return --- vlib/v/checker/checker.v | 6 ++++++ vlib/v/parser/parser.v | 2 +- vlib/v/tests/goto_test.v | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 12f199d35d..2d6de47363 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5162,6 +5162,12 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) { } } c.stmt(stmt) + if stmt is ast.GotoLabel { + unreachable = token.Position{ + line_nr: -1 + } + c.scope_returns = false + } } if unreachable.line_nr >= 0 { c.error('unreachable code', unreachable) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index bfdcd0d006..da1adff5dc 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2974,7 +2974,7 @@ fn (mut p Parser) return_stmt() ast.Return { p.next() // no return mut comments := p.eat_comments() - if p.tok.kind == .rcbr { + if p.tok.kind == .rcbr || ( p.tok.kind == .name && p.peek_tok.kind == .colon ) { return ast.Return{ comments: comments pos: first_pos diff --git a/vlib/v/tests/goto_test.v b/vlib/v/tests/goto_test.v index b4654739ba..02b23a86e7 100644 --- a/vlib/v/tests/goto_test.v +++ b/vlib/v/tests/goto_test.v @@ -11,3 +11,28 @@ fn test_goto() { } assert i == 3 } + +pub fn test_goto_after_return() { + a, b, c, d := 4, 5, 6, 7 + for { + for { + for { + if a == 4 { + if b == 5 { + if c == 6 { + if d == 7 { + unsafe { + goto finally_ok + } + } + } + } + } + } + } + } + assert false + return + finally_ok: + assert true +}