v icon indicating copy to clipboard operation
v copied to clipboard

arrays: buggy result for arrays.concat/2, and a runtime panic with `-gc none`

Open spytheman opened this issue 2 years ago • 4 comments

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.

spytheman avatar Apr 01 '23 12:04 spytheman

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.

spytheman avatar Apr 01 '23 12:04 spytheman

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)
      |      ~~~~~~~~~~~~

spytheman avatar Apr 01 '23 14:04 spytheman

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)

spytheman avatar Apr 01 '23 14:04 spytheman

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.

spytheman avatar Apr 01 '23 14:04 spytheman