v
v copied to clipboard
arrays: buggy result for arrays.concat/2, and a runtime panic with `-gc none`
V doctor:
V full version: V 0.3.3 5b8d6c0
OS: linux, Ubuntu 20.04.5 LTS
Processor: 4 cpus, 64bit, little endian, Intel(R) Core(TM) i3-3225 CPU @ 3.30GHz
getwd: /v/vnew
vexe: /v/vnew/v
vexe mtime: 2023-04-01 08:07:08
vroot: OK, value: /v/vnew
VMODULES: OK, value: /home/delian/.vmodules
VTMP: OK, value: /tmp/v_1000
Git version: git version 2.40.0
Git vroot status: weekly.2023.13-29-g5b8d6c0a-dirty
.git/config present: true
CC version: cc (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
thirdparty/tcc status: thirdparty-linux-amd64 12f392c3
What did you do?
v -g -o vdbg cmd/v && vdbg arrays_concat_runtime_panic.v
import arrays
a := [['0']]
b := [['aa', 'bb']]
c := arrays.concat(a, b)
dump(c)
What did you expect to see?
[arrays_concat_runtime_panic.v:6] c: [['0'], ['aa', 'bb']]
What did you see instead?
[arrays_concat_runtime_panic.v:6] c: [['0'], ['']]
Note: v -g -gc none run arrays_concat_runtime_panic.v
leads to a panic at runtime, so perhaps the problem is cgen (the code handling passing an array as a variadic parameter). The data in the result is invalid, but that is masked by the garbage collector, thus the need for -gc none:
#255 15:01:27 ᛋ master /v/vnew❱v -g -gc none run arrays_concat_runtime_panic.v
7ffff7e47d58 : at ???: RUNTIME ERROR: invalid memory access
/tmp/v_1000/../../../../../../v/vnew/vlib/builtin/array.v:698: by array_push_many
/tmp/v_1000/../../../../../../v/vnew/vlib/strings/builder.c.v:108: by strings__Builder_write_string
/tmp/v_1000/../../../../../../v/vnew/vlib/builtin/array.v:900: by Array_string_str
/tmp/v_1000/arrays_concat_runtime_panic.15191367519460428297.tmp.c:2093: by indent_Array_Array_string_str
/tmp/v_1000/arrays_concat_runtime_panic.15191367519460428297.tmp.c:2086: by Array_Array_string_str
/tmp/v_1000/arrays_concat_runtime_panic.15191367519460428297.tmp.c:2108: by _v_dump_expr_Array_Array_string
/tmp/v_1000/../../../../../../v/vnew/arrays_concat_runtime_panic.v:6: by main__main
/tmp/v_1000/../../../../../../tmp/v_1000/arrays_concat_runtime_panic.15191367519460428297.tmp.c:17329: by main
The code for concat is currently:
pub fn concat[T](a []T, b ...T) []T {
mut m := []T{cap: a.len + b.len}
m << a
m << b
return m
}
Note that b is passed as a variadic parameter.
A simpler self contained reproduction is with:
pub fn concat[T](a []T, b ...T) []T {
mut m := []T{cap: a.len + b.len}
m << a
m << b
return m
}
a := [['0']]
b := [['aa', 'bb']]
c := concat(a, b)
println(c)
Run with: v -gc none run variadic_generic_array_append_bug.v
Note: changing the signature to pub fn concat[T](a []T, b []T) []T { fixes it.
pub fn concat(a [][]string, b ...[]string) [][]string {
mut m := [][]string{cap: a.len + b.len}
m << a
m << b
return m
}
a := [['0']]
b := [['aa', 'bb']]
c := concat(a, ...b)
println(c)
also works fine with v -gc none run oo.v
It triggers an error with just calling concat(a,b):
oo.v:10:6: error: to pass `b` ([][]string) to `concat` (which accepts type `...[]string`), use `...b`
8 | a := [['0']]
9 | b := [['aa', 'bb']]
10 | c := concat(a, b)
| ~~~~~~~~~~~~
This is also fine:
pub fn concat[T](a []T, b ...T) []T {
mut m := []T{cap: a.len + b.len}
m << a
m << b
return m
}
a := [['0']]
b := [['aa', 'bb']]
c := concat(a, ...b)
println(c)
A valid fix, may be also to extend the error from vlib/v/checker/fn.v:1009:c.error to apply to the generic function call as well.