mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser: disallow statements after a return, branch check $if, $else, switch, and loops correctly
This commit is contained in:

committed by
Alexander Medvednikov

parent
58b52aa9fb
commit
1864e92ff4
@ -102,7 +102,6 @@ fn platform_postfix_to_ifdefguard(name string) string {
|
||||
case '_mac.v': return '#ifdef __APPLE__'
|
||||
}
|
||||
panic('bad platform_postfix "$name"')
|
||||
return ''
|
||||
}
|
||||
|
||||
fn (v mut V) new_parser(path string, pass Pass) Parser {
|
||||
@ -296,7 +295,6 @@ fn (p mut Parser) parse() {
|
||||
if false && !p.first_pass() && p.fileis('main.v') {
|
||||
out := os.create('/var/tmp/fmt.v') or {
|
||||
panic('failed to create fmt.v')
|
||||
return
|
||||
}
|
||||
out.writeln(p.scanner.fmt_out.str())
|
||||
out.close()
|
||||
@ -1103,6 +1101,9 @@ fn (p mut Parser) vh_genln(s string) {
|
||||
}
|
||||
|
||||
fn (p mut Parser) statement(add_semi bool) string {
|
||||
if(p.returns) {
|
||||
p.error('unreachable code')
|
||||
}
|
||||
p.cgen.is_tmp = false
|
||||
tok := p.tok
|
||||
mut q := ''
|
||||
@ -1321,6 +1322,7 @@ fn (p mut Parser) var_decl() {
|
||||
if !p.returns && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break {
|
||||
p.error('`or` block must return/continue/break/panic')
|
||||
}
|
||||
p.returns = false
|
||||
}
|
||||
p.register_var(Var {
|
||||
name: name
|
||||
@ -1983,7 +1985,6 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||
p.cgen.insert_before('$typ $tmp = $tmp_val;')
|
||||
}
|
||||
return typ
|
||||
return 'void'
|
||||
}
|
||||
// else if p.pref.is_verbose && p.assigned_var != '' {
|
||||
// p.error('didnt assign')
|
||||
@ -2905,7 +2906,6 @@ fn os_name_to_ifdef(name string) string {
|
||||
case 'msvc': return '_MSC_VER'
|
||||
}
|
||||
panic('bad os ifdef name "$name"')
|
||||
return ''
|
||||
}
|
||||
|
||||
fn (p mut Parser) if_st(is_expr bool, elif_depth int) string {
|
||||
@ -3167,6 +3167,7 @@ fn (p mut Parser) for_st() {
|
||||
p.statements()
|
||||
p.close_scope()
|
||||
p.for_expr_cnt--
|
||||
p.returns = false // TODO handle loops that are guaranteed to return
|
||||
}
|
||||
|
||||
fn (p mut Parser) switch_statement() {
|
||||
@ -3180,7 +3181,9 @@ fn (p mut Parser) switch_statement() {
|
||||
expr := p.cgen.end_tmp()
|
||||
p.check(.lcbr)
|
||||
mut i := 0
|
||||
mut all_cases_return := true
|
||||
for p.tok == .key_case || p.tok == .key_default || p.peek() == .arrow || p.tok == .key_else {
|
||||
p.returns = false
|
||||
if p.tok == .key_default || p.tok == .key_else {
|
||||
p.genln('else { // default:')
|
||||
if p.tok == .key_default {
|
||||
@ -3191,7 +3194,8 @@ fn (p mut Parser) switch_statement() {
|
||||
p.check(.arrow)
|
||||
}
|
||||
p.statements()
|
||||
break
|
||||
p.returns = all_cases_return && p.returns
|
||||
return
|
||||
}
|
||||
if i > 0 {
|
||||
p.gen('else ')
|
||||
@ -3228,8 +3232,10 @@ fn (p mut Parser) switch_statement() {
|
||||
p.gen(')) {')
|
||||
p.genln('/* case */')
|
||||
p.statements()
|
||||
all_cases_return = all_cases_return && p.returns
|
||||
i++
|
||||
}
|
||||
p.returns = false // only get here when no default, so return is not guaranteed
|
||||
}
|
||||
|
||||
fn (p mut Parser) assert_statement() {
|
||||
|
Reference in New Issue
Block a user