From 00563a130dfcac911e0ffbe871ea2b9ff9239172 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 18 Mar 2022 09:43:15 +0000 Subject: [PATCH] cgen: fix double evaluation of rvalue array expression in slice (#13737) --- vlib/v/gen/c/cgen.v | 5 +++-- vlib/v/gen/c/index.v | 32 ++++++++++++++++++++++++-------- vlib/v/tests/slice_rval_test.v | 8 ++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 vlib/v/tests/slice_rval_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index d576ede838..0c6b879a10 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4795,7 +4795,7 @@ fn (mut g Gen) go_before_ternary() string { } fn (mut g Gen) insert_before_stmt(s string) { - cur_line := g.go_before_stmt(0) + cur_line := g.go_before_stmt(g.inside_ternary) g.writeln(s) g.write(cur_line) } @@ -5643,7 +5643,8 @@ static inline __shared__$interface_name ${shared_fn_name}(__shared__$cctype* x) if fargs.len > 1 { methods_wrapper.write_string(', ') } - methods_wrapper.writeln('${fargs[1..].join(', ')});') + args := fargs[1..].join(', ') + methods_wrapper.writeln('$args);') } else { if parameter_name.starts_with('__shared__') { methods_wrapper.writeln('${method_call}(${fargs.join(', ')}->val);') diff --git a/vlib/v/gen/c/index.v b/vlib/v/gen/c/index.v index 08a041d9d5..8ff1dd7633 100644 --- a/vlib/v/gen/c/index.v +++ b/vlib/v/gen/c/index.v @@ -62,6 +62,7 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) { mut tmp_opt := '' mut cur_line := '' mut gen_or := node.or_expr.kind != .absent || node.is_option + mut tmp_left := '' if sym.kind == .string { if node.is_gated { @@ -82,6 +83,15 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) { } g.expr(node.left) } else if sym.kind == .array { + if !range.has_high { + tmp_left = g.new_tmp_var() + tmp_type := g.typ(node.left_type) + g.insert_before_stmt('${util.tabs(g.indent)}$tmp_type $tmp_left;') + // (tmp = expr, array_slice(...)) + g.write('($tmp_left = ') + g.expr(node.left) + g.write(', ') + } if node.is_gated { g.write('array_slice_ni(') } else { @@ -90,7 +100,11 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) { if node.left_type.is_ptr() { g.write('*') } - g.expr(node.left) + if range.has_high { + g.expr(node.left) + } else { + g.write(tmp_left) + } } else if sym.kind == .array_fixed { // Convert a fixed array to V array when doing `fixed_arr[start..end]` info := sym.info as ast.ArrayFixed @@ -132,15 +146,17 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) { } else if sym.kind == .array_fixed { info := sym.info as ast.ArrayFixed g.write('$info.size') - } else if node.left_type.is_ptr() { - g.write('(') - g.write('*') - g.expr(node.left) - g.write(')') - g.write('.len') + } else if sym.kind == .array { + if node.left_type.is_ptr() { + g.write('$tmp_left->') + } else { + g.write('${tmp_left}.') + } + g.write('len)') } else { + g.write('(') g.expr(node.left) - g.write('.len') + g.write(').len') } g.write(')') diff --git a/vlib/v/tests/slice_rval_test.v b/vlib/v/tests/slice_rval_test.v new file mode 100644 index 0000000000..2078f5b353 --- /dev/null +++ b/vlib/v/tests/slice_rval_test.v @@ -0,0 +1,8 @@ +fn test_arr_rval() { + a := [1, 2] + s := (*&a)[..] + assert s == a + + b := unsafe { *&[]int(&a) }[..] + assert b == a +}