From dd0b68ac90dd49e6222653385cc3242f619af184 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 29 Mar 2023 19:51:29 +0800 Subject: [PATCH] checker: check if guard returning non-propagate option or result (fix #17742) (#17794) --- examples/tcp_notify_echo_server.v | 12 ++++++------ vlib/v/checker/if.v | 5 +++++ vlib/v/checker/tests/if_guard_expr_err.out | 7 +++++++ vlib/v/checker/tests/if_guard_expr_err.vv | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 vlib/v/checker/tests/if_guard_expr_err.out create mode 100644 vlib/v/checker/tests/if_guard_expr_err.vv diff --git a/examples/tcp_notify_echo_server.v b/examples/tcp_notify_echo_server.v index 4360235917..87b2fbbc44 100644 --- a/examples/tcp_notify_echo_server.v +++ b/examples/tcp_notify_echo_server.v @@ -37,11 +37,11 @@ fn main() { // someone is trying to connect eprint('trying to connect.. ') if conn := listener.accept() { - if _ := notifier.add(conn.sock.handle, .read | .peer_hangup) { - eprintln('connected') - } else { + notifier.add(conn.sock.handle, .read | .peer_hangup) or { eprintln('error adding to notifier: ${err}') + return } + eprintln('connected') } else { eprintln('unable to accept: ${err}') } @@ -57,11 +57,11 @@ fn main() { else { // remote connection if event.kind.has(.peer_hangup) { - if _ := notifier.remove(event.fd) { - eprintln('remote disconnected') - } else { + notifier.remove(event.fd) or { eprintln('error removing from notifier: ${err}') + return } + eprintln('remote disconnected') } else { s, _ := os.fd_read(event.fd, 10) os.fd_write(event.fd, s) diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 0a4166d763..91134d102a 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -71,6 +71,11 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } } if mut branch.cond is ast.IfGuardExpr { + if branch.cond.expr_type.clear_flag(.option).clear_flag(.result) == ast.void_type + && !(branch.cond.vars.len == 1 && branch.cond.vars[0].name == '_') { + c.error('if guard expects non-propagate option or result', branch.pos) + continue + } sym := c.table.sym(branch.cond.expr_type) if sym.kind == .multi_return { mr_info := sym.info as ast.MultiReturn diff --git a/vlib/v/checker/tests/if_guard_expr_err.out b/vlib/v/checker/tests/if_guard_expr_err.out new file mode 100644 index 0000000000..66e441da83 --- /dev/null +++ b/vlib/v/checker/tests/if_guard_expr_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/if_guard_expr_err.vv:6:7: error: if guard expects non-propagate option or result + 4 | + 5 | fn main() { + 6 | a := if r := foo() { + | ~~~~~~~~~~~~~ + 7 | println(r) + 8 | true diff --git a/vlib/v/checker/tests/if_guard_expr_err.vv b/vlib/v/checker/tests/if_guard_expr_err.vv new file mode 100644 index 0000000000..cf74a162b0 --- /dev/null +++ b/vlib/v/checker/tests/if_guard_expr_err.vv @@ -0,0 +1,14 @@ +fn foo() ! { + return error("error") +} + +fn main() { + a := if r := foo() { + println(r) + true + } else { + false + } + + println(a) +}