Skip to content

Commit

Permalink
cgen: fix multiple fixed array variable init (fix #20895) (#20902)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Feb 25, 2024
1 parent ee045ed commit ac62317
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 13 deletions.
28 changes: 18 additions & 10 deletions vlib/v/gen/c/array.v
Expand Up @@ -56,7 +56,8 @@ fn (mut g Gen) array_init(node ast.ArrayInit, var_name string) {
} else if elem_type.unaliased_sym.kind == .array_fixed
&& expr in [ast.Ident, ast.SelectorExpr] {
info := elem_type.unaliased_sym.info as ast.ArrayFixed
g.fixed_array_var_init(expr, info.size)
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
info.elem_type, info.size)
} else {
g.expr_with_cast(expr, node.expr_types[i], node.elem_type)
}
Expand Down Expand Up @@ -162,7 +163,8 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st
for i, expr in node.exprs {
if elem_sym.kind == .array_fixed && expr in [ast.Ident, ast.SelectorExpr] {
info := elem_sym.info as ast.ArrayFixed
g.fixed_array_var_init(expr, info.size)
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
info.elem_type, info.size)
} else {
if expr.is_auto_deref_var() {
g.write('*')
Expand Down Expand Up @@ -1339,17 +1341,23 @@ fn (mut g Gen) write_prepared_var(var_name string, inp_info ast.Array, inp_elem_
}
}

fn (mut g Gen) fixed_array_var_init(expr ast.Expr, size int) {
fn (mut g Gen) fixed_array_var_init(expr_str string, is_auto_deref bool, elem_type ast.Type, size int) {
g.write('{')
for i in 0 .. size {
if expr.is_auto_deref_var() {
g.write('(*')
}
g.expr(expr)
if expr.is_auto_deref_var() {
g.write(')')
elem_sym := g.table.sym(elem_type)
if elem_sym.info is ast.ArrayFixed {
g.fixed_array_var_init('${expr_str}[${i}]', is_auto_deref, elem_sym.info.elem_type,
elem_sym.info.size)
} else {
if is_auto_deref {
g.write('(*')
}
g.write(expr_str)
if is_auto_deref {
g.write(')')
}
g.write('[${i}]')
}
g.write('[${i}]')
if i != size - 1 {
g.write(', ')
}
Expand Down
8 changes: 6 additions & 2 deletions vlib/v/gen/c/cgen.v
Expand Up @@ -5397,7 +5397,9 @@ fn (mut g Gen) return_stmt(node ast.Return) {
}
for i, expr in node.exprs {
if return_sym.kind == .array_fixed && expr !is ast.ArrayInit {
g.fixed_array_var_init(expr, (return_sym.info as ast.ArrayFixed).size)
info := return_sym.info as ast.ArrayFixed
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
info.elem_type, info.size)
} else {
g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_option_and_result())
}
Expand Down Expand Up @@ -5432,7 +5434,9 @@ fn (mut g Gen) return_stmt(node ast.Return) {
if fn_ret_type.has_flag(.option) {
g.expr_with_opt(expr, node.types[i], fn_ret_type.clear_flag(.result))
} else if return_sym.kind == .array_fixed && expr !is ast.ArrayInit {
g.fixed_array_var_init(expr, (return_sym.info as ast.ArrayFixed).size)
info := return_sym.info as ast.ArrayFixed
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
info.elem_type, info.size)
} else {
g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_flag(.result))
}
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/gen/c/struct.v
Expand Up @@ -603,7 +603,8 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua
field_unwrap_sym := g.table.sym(g.unwrap_generic(sfield.typ))
if field_unwrap_sym.kind == .array_fixed && sfield.expr in [ast.Ident, ast.SelectorExpr] {
info := field_unwrap_sym.info as ast.ArrayFixed
g.fixed_array_var_init(sfield.expr, info.size)
g.fixed_array_var_init(g.expr_string(sfield.expr), sfield.expr.is_auto_deref_var(),
info.elem_type, info.size)
} else {
if sfield.typ != ast.voidptr_type && sfield.typ != ast.nil_type
&& (sfield.expected_type.is_ptr() && !sfield.expected_type.has_flag(.shared_f))
Expand Down
41 changes: 41 additions & 0 deletions vlib/v/tests/multiple_fixed_array_var_init_test.v
@@ -0,0 +1,41 @@
struct Cell {
value int
fvalue f32
mut:
mut_value int = 10
mut_fvalue f32
}

struct Grid {
cells [2][2][2]Cell
}

fn test_multiple_fixed_array_var_init() {
mut tile_field := [2][2][2]Cell{}

b := Grid{
cells: tile_field
}

println('The original:')
println(tile_field)
println('==========')
println('The struct:')
println(b.cells)
assert b.cells[0][0][0].value == 0
assert b.cells[0][0][0].mut_value == 10
assert b.cells[0][0][1].value == 0
assert b.cells[0][0][1].mut_value == 10
assert b.cells[0][1][0].value == 0
assert b.cells[0][1][0].mut_value == 10
assert b.cells[0][1][1].value == 0
assert b.cells[0][1][1].mut_value == 10
assert b.cells[1][0][0].value == 0
assert b.cells[1][0][0].mut_value == 10
assert b.cells[1][0][1].value == 0
assert b.cells[1][0][1].mut_value == 10
assert b.cells[1][1][0].value == 0
assert b.cells[1][1][0].mut_value == 10
assert b.cells[1][1][1].value == 0
assert b.cells[1][1][1].mut_value == 10
}

0 comments on commit ac62317

Please sign in to comment.