From f8827c3fe57f8aca8cbec4a9f0d690d0e5a02c50 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 22 Nov 2020 13:22:42 +0100 Subject: [PATCH] builtin: clone the strings correctly in array.push --- vlib/builtin/array.v | 2 +- vlib/builtin/array_test.v | 11 +++++++++++ vlib/v/gen/cgen.v | 10 +++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index a8966d6e55..d4088d375c 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -389,7 +389,7 @@ fn (mut a array) set(i int, val voidptr) { fn (mut a array) push(val voidptr) { a.ensure_cap(a.len + 1) - unsafe {C.memcpy(byteptr(a.data) + a.element_size * a.len, val, a.element_size)} + unsafe {C.memmove(byteptr(a.data) + a.element_size * a.len, val, a.element_size)} a.len++ } diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index 482107e908..f1c9fbe1d0 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -1032,6 +1032,17 @@ fn test_direct_array_access_via_ptr() { } } +fn test_push_arr_string_free() { + mut lines := ['hi'] + s := 'a' + 'b' + lines << s + s.free() // make sure the data in the array is valid after freeing the string + println(lines) + assert lines.len == 2 + assert lines[0] == 'hi' + assert lines[1] == 'ab' +} + const ( grid_size_1 = 2 grid_size_2 = 3 diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 834ac4ea16..2e45ea10b5 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2907,11 +2907,19 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { } else { g.write(', _MOV(($elem_type_str[]){ ') } + is_interface := elem_sym.kind == .interface_ && node.right_type != info.elem_type if elem_sym.kind == .interface_ && node.right_type != info.elem_type { g.interface_call(node.right_type, info.elem_type) } + // if g.pref.autofree && info.elem_type == table.string_type { + if info.elem_type == table.string_type { + g.write('string_clone(') + } g.expr_with_cast(node.right, node.right_type, info.elem_type) - if elem_sym.kind == .interface_ && node.right_type != info.elem_type { + if info.elem_type == table.string_type { + g.write(')') + } + if is_interface { g.write(')') } g.write(' }))')