From c48ae86132e246aa5c34226fecac9848160973c5 Mon Sep 17 00:00:00 2001 From: Mark aka walkingdevel <104449470+walkingdevel@users.noreply.github.com> Date: Mon, 3 Jul 2023 05:01:55 +0000 Subject: [PATCH] cgen: fix autofree inserting string declarations for multiple functions calls (#18723) --- vlib/v/gen/c/cgen.v | 10 ++++++++-- vlib/v/gen/c/fn.v | 2 +- vlib/v/gen/c/text_manipulation.v | 10 ++++++++++ vlib/v/slow_tests/valgrind/multiple_fn_calls.v | 13 +++++++++++++ vlib/v/slow_tests/valgrind/valgrind_test.v | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 vlib/v/slow_tests/valgrind/multiple_fn_calls.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index d7573221d..a5db6a4b3 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3121,7 +3121,12 @@ fn (mut g Gen) expr(node_ ast.Expr) { g.writeln('(${shared_styp}*)__dup${shared_styp}(&(${shared_styp}){.mtx = {0}, .val =') } } - last_stmt_pos := if g.stmt_path_pos.len > 0 { g.stmt_path_pos.last() } else { 0 } + stmt_before_call_expr_pos := if g.stmt_path_pos.len > 0 { + g.stmt_path_pos.last() + } else { + 0 + } + g.call_expr(node) if g.is_autofree && !g.is_builtin_mod && !g.is_js_call && g.strs_to_free0.len == 0 && !g.inside_lambda { @@ -3130,7 +3135,8 @@ fn (mut g Gen) expr(node_ ast.Expr) { // so just skip it g.autofree_call_pregen(node) if g.strs_to_free0.len > 0 { - g.insert_at(last_stmt_pos, g.strs_to_free0.join('\n') + '/* inserted before */') + g.insert_at(stmt_before_call_expr_pos, g.strs_to_free0.join('\n') + + '/* inserted before */') } g.strs_to_free0 = [] } diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 6d9cbbea2..587554b6f 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2021,7 +2021,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) { fn_name := node.name.replace('.', '_') // name := '_tt${g.tmp_count_af}_arg_expr_${fn_name}_$i' name := '_arg_expr_${fn_name}_${i + 1}_${node.pos.pos}' - g.write('/*af arg*/' + name) + g.write('/*autofree arg*/' + name) } } else { g.ref_or_deref_arg(arg, expected_types[i], node.language) diff --git a/vlib/v/gen/c/text_manipulation.v b/vlib/v/gen/c/text_manipulation.v index ac2454df7..f0bba212d 100644 --- a/vlib/v/gen/c/text_manipulation.v +++ b/vlib/v/gen/c/text_manipulation.v @@ -84,4 +84,14 @@ fn (mut g Gen) insert_at(pos int, s string) { // g.out_parallel[g.out_idx].cut_to(pos) g.writeln(s) g.write(cur_line) + + // After modifying the code in the buffer, we need to adjust the positions of the statements + // to account for the added line of code. + // This is necessary to ensure that autofree can properly insert string declarations + // in the correct positions, considering the surgically made changes. + for index, stmt_pos in g.stmt_path_pos { + if stmt_pos >= pos { + g.stmt_path_pos[index] += s.len + 1 + } + } } diff --git a/vlib/v/slow_tests/valgrind/multiple_fn_calls.v b/vlib/v/slow_tests/valgrind/multiple_fn_calls.v new file mode 100644 index 000000000..04dfdc5e4 --- /dev/null +++ b/vlib/v/slow_tests/valgrind/multiple_fn_calls.v @@ -0,0 +1,13 @@ +import strconv + +fn color_code_to_rgb(color string) []int { + clr := color.replace('#', '') + return [int(strconv.parse_int(clr[0..2], 16, 0) or { return [0, 0, 0] }), + int(strconv.parse_int(clr[2..4], 16, 0) or { return [0, 0, 0] }), + int(strconv.parse_int(clr[4..6], + 16, 0) or { return [0, 0, 0] })] +} + +fn main() { + dump(color_code_to_rgb('#abcdef')) +} diff --git a/vlib/v/slow_tests/valgrind/valgrind_test.v b/vlib/v/slow_tests/valgrind/valgrind_test.v index ca1205ad2..6a0369d20 100644 --- a/vlib/v/slow_tests/valgrind/valgrind_test.v +++ b/vlib/v/slow_tests/valgrind/valgrind_test.v @@ -27,6 +27,7 @@ const skip_valgrind_files = [ 'vlib/v/slow_tests/valgrind/struct_field.v', 'vlib/v/slow_tests/valgrind/fn_returning_string_param.v', 'vlib/v/slow_tests/valgrind/fn_with_return_should_free_local_vars.v', + 'vlib/v/slow_tests/valgrind/multiple_fn_calls.v', 'vlib/v/slow_tests/valgrind/option_simple.v', 'vlib/v/slow_tests/valgrind/string_plus_string_plus.v', 'vlib/v/slow_tests/valgrind/import_x_json2.v', -- 2.39.5