From a1827d7f9806de1df8b4384f0f87cf3f94e3b98c Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 22 Nov 2020 20:48:10 +0100 Subject: [PATCH] autofree: handle array set/get --- vlib/v/gen/cgen.v | 19 +++++++++++++++++-- vlib/v/tests/valgrind/1.strings_and_arrays.v | 6 ++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index abefafe27a..0c26b84885 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1536,6 +1536,7 @@ fn (mut g Gen) write_fn_ptr_decl(func &table.FnType, ptr_name string) { g.write(')') } +// TODO this function is scary. Simplify/split up. fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if assign_stmt.is_static { g.write('static ') @@ -1683,7 +1684,14 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if left.left_type.is_ptr() { g.write('*') } + needs_clone := elem_typ == table.string_type && g.pref.autofree + if needs_clone { + g.write('/*1*/string_clone(') + } g.expr(left.left) + if needs_clone { + g.write(')') + } g.write(', ') g.expr(left.index) g.writeln(');') @@ -3750,10 +3758,15 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) { .function { 'voidptr*' } else { '$elem_type_str*' } } + needs_clone := info.elem_type == table.string_type_idx && g.pref.autofree && + !g.is_assign_lhs + if needs_clone { + g.write('/*2*/string_clone(') + } if is_direct_array_access { g.write('(($array_ptr_type_str)') } else { - g.write('(*($array_ptr_type_str)array_get(') + g.write('(*($array_ptr_type_str)/*ee elem_typ */array_get(') if left_is_ptr && !node.left_type.has_flag(.shared_f) { g.write('*') } @@ -3781,6 +3794,9 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) { g.expr(node.index) g.write('))') } + if needs_clone { + g.write(')') + } } } else if sym.kind == .map { info := sym.info as table.Map @@ -3900,7 +3916,6 @@ fn (mut g Gen) return_statement(node ast.Return, af bool) { if af { // free the tmp arg expr if we have one before the return g.autofree_call_postgen(node.pos.pos) - // g.strs_to_free = [] } styp := g.typ(g.fn_decl.return_type) g.writeln('return *($styp*)&$tmp;') diff --git a/vlib/v/tests/valgrind/1.strings_and_arrays.v b/vlib/v/tests/valgrind/1.strings_and_arrays.v index 6e89ed5664..b1a93321f1 100644 --- a/vlib/v/tests/valgrind/1.strings_and_arrays.v +++ b/vlib/v/tests/valgrind/1.strings_and_arrays.v @@ -256,6 +256,12 @@ fn get_user() User { return user } +fn string_array_get() { + s := ['a', 'b', 'c'] + x := s[0] + println(s) +} + fn main() { println('start') simple()