builtin: clone the strings correctly in array.push

pull/6913/head
Alexander Medvednikov 2020-11-22 13:22:42 +01:00
parent ed7413ee51
commit f8827c3fe5
3 changed files with 21 additions and 2 deletions

View File

@ -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++
}

View File

@ -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

View File

@ -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(' }))')