Skip to content

Commit

Permalink
cgen: fix array to alias push operation (fix #22374) (#22375)
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Oct 1, 2024
1 parent aa3ab3f commit ce95787
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 11 deletions.
22 changes: 22 additions & 0 deletions vlib/v/ast/types.v
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,28 @@ fn (ts TypeSymbol) dbg_common(mut res []string) {
res << 'language: ${ts.language}'
}

pub fn (ts TypeSymbol) nr_dims() int {
match ts.info {
Alias {
parent_sym := global_table.sym(ts.info.parent_type)
if parent_sym.info is Array {
return parent_sym.info.nr_dims
}
return 0
}
Array {
elem_sym := global_table.sym(ts.info.elem_type)
if elem_sym.info is Alias {
return ts.info.nr_dims + elem_sym.nr_dims()
}
return ts.info.nr_dims
}
else {
return 0
}
}
}

// str returns a string representation of the type.
pub fn (t Type) str() string {
return 'ast.Type(0x${t.hex()} = ${u32(t)})'
Expand Down
11 changes: 1 addition & 10 deletions vlib/v/checker/containers.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import v.token

fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
mut elem_type := ast.void_type
mut unwrap_elem_type := c.unwrap_generic(node.elem_type)
unwrap_elem_type := c.unwrap_generic(node.elem_type)
if c.pref.warn_about_allocs {
c.warn_alloc('array initialization', node.pos)
}
Expand Down Expand Up @@ -60,15 +60,6 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
if elem_sym.name == 'byte' {
c.warn('byte is deprecated, use u8 instead', node.elem_type_pos)
}
parent_sym := c.table.sym(elem_sym.info.parent_type)
// check array to aliased array type
if parent_sym.info is ast.Array {
node.alias_type = c.table.find_or_register_array(unwrap_elem_type)
node.elem_type = c.table.find_or_register_array_with_dims(parent_sym.info.elem_type,
parent_sym.info.nr_dims)
unwrap_elem_type = node.elem_type
node.typ = c.table.find_or_register_array(node.elem_type)
}
}
else {}
}
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/gen/c/infix.v
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,8 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) {
noscan := g.check_noscan(array_info.elem_type)
if (right.unaliased_sym.kind == .array
|| (right.unaliased_sym.kind == .struct_ && right.unaliased_sym.name == 'array'))
&& array_info.elem_type != right.typ && !(right.sym.kind == .alias
&& left.sym.nr_dims() == right.sym.nr_dims() && array_info.elem_type != right.typ
&& !(right.sym.kind == .alias
&& g.table.sumtype_has_variant(array_info.elem_type, node.right_type, false)) {
// push an array => PUSH_MANY, but not if pushing an array to 2d array (`[][]int << []int`)
g.write('_PUSH_MANY${noscan}(')
Expand Down
19 changes: 19 additions & 0 deletions vlib/v/tests/aliases/alias_array_push_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module main

type NLRI = []u8

fn make_loopback() []NLRI {
raw := [u8(32), 10, 0, 0, 1]
mut nlris := []NLRI{cap: 1}
nlris << NLRI(raw[0..5])
return nlris
}

fn test_main() {
r := make_loopback()
assert r[0][0] == 32
assert r[0][1] == 10
assert r[0][2] == 0
assert r[0][3] == 0
assert r[0][4] == 1
}

0 comments on commit ce95787

Please sign in to comment.