From d9a300cacc32635e5b4f9109ba156652cf1d4669 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 27 Jun 2024 13:35:13 +0800 Subject: [PATCH] cgen: fix shortcircuiting of infix and/or expressions (#21740) --- vlib/v/gen/c/infix.v | 16 ++++++++++++++++ ..._expr_and_or_operate_unnecessary_eval_test.v | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 vlib/v/tests/infix_expr_and_or_operate_unnecessary_eval_test.v diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 31c1319d6671de..529039b85b557a 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -1057,6 +1057,22 @@ fn (mut g Gen) infix_expr_and_or_op(node ast.InfixExpr) { return } } + } else if node.right is ast.InfixExpr && g.need_tmp_var_in_expr(node.right) { + prev_inside_ternary := g.inside_ternary + g.inside_ternary = 0 + tmp := g.new_tmp_var() + cur_line := g.go_before_last_stmt().trim_space() + g.empty_line = true + g.write('bool ${tmp} = (') + g.expr(node.left) + g.writeln(');') + g.set_current_pos_as_last_stmt_pos() + g.write('${cur_line} ${tmp} ${node.op.str()} ') + g.infix_left_var_name = if node.op == .and { tmp } else { '!${tmp}' } + g.expr(node.right) + g.infix_left_var_name = '' + g.inside_ternary = prev_inside_ternary + return } g.gen_plain_infix_expr(node) } diff --git a/vlib/v/tests/infix_expr_and_or_operate_unnecessary_eval_test.v b/vlib/v/tests/infix_expr_and_or_operate_unnecessary_eval_test.v new file mode 100644 index 00000000000000..60f4872652880d --- /dev/null +++ b/vlib/v/tests/infix_expr_and_or_operate_unnecessary_eval_test.v @@ -0,0 +1,17 @@ +fn f(s string) !int { + if s == '' { + return error('invalid s') + } + return s.len +} + +fn test_infix_expr_and_or_operate_unnecessary_eval() { + v := '' + x := v != 'xyz' || f(v)! < f('abc')! + dump(x) + assert x + + y := v == 'xyz' && f(v)! < f('abc')! + dump(y) + assert !y +}