diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index e312755d249629..acb93f79c4c100 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2768,10 +2768,23 @@ fn (mut g Gen) expr_with_fixed_array(expr ast.Expr, got_type_raw ast.Type, expec g.writeln('${styp} ${tmp_var};') // [ foo(), foo() ]! val_typ := g.table.value_type(got_type_raw) + val_styp := g.styp(val_typ) + val_sym := g.table.final_sym(val_typ) + prefix := if val_sym.kind !in [.array, .array_fixed] { '&' } else { '' } for i, item_expr in expr.exprs { - g.write('memcpy(${tmp_var}[${i}], ') + g.write('memcpy(${prefix}${tmp_var}[${i}], ') + needs_addr := (item_expr is ast.CallExpr && !item_expr.return_type.is_ptr() + && g.table.final_sym(item_expr.return_type).kind !in [.array, .array_fixed]) + || (item_expr is ast.InfixExpr && !item_expr.promoted_type.is_ptr()) + || item_expr is ast.StructInit + if needs_addr { + g.write('ADDR(${val_styp}, ') + } g.expr(item_expr) - g.writeln(', sizeof(${g.styp(val_typ)}));') + if needs_addr { + g.write(')') + } + g.writeln(', sizeof(${val_styp}));') } } else if expr is ast.CallExpr { // return var.call() where returns is option/result fixed array diff --git a/vlib/v/tests/builtin_arrays/array_fixed_init_node_test.v b/vlib/v/tests/builtin_arrays/array_fixed_init_node_test.v new file mode 100644 index 00000000000000..28a5e1829d8433 --- /dev/null +++ b/vlib/v/tests/builtin_arrays/array_fixed_init_node_test.v @@ -0,0 +1,50 @@ +module main + +import math.vec + +pub struct Bezier { +pub mut: + points [4]vec.Vec2[f32] +} + +pub fn (b Bezier) h3() vec.Vec2[f32] { + return b.points[2] +} + +pub fn (b Bezier) h4() vec.Vec2[f32] { + return b.points[3] +} + +pub fn (b Bezier) end() vec.Vec2[f32] { + return b.h4() +} + +pub struct Path { +pub mut: + segments [1024]Bezier + len int // should be read-only +} + +pub fn (mut p Path) add(b Bezier) { + assert p.len + 1 < 1024 + p.segments[p.len] = b + p.len++ +} + +fn test_main() { + b1 := Bezier{ + points: [vec.Vec2[f32]{100, 100}, vec.Vec2[f32]{120, 80}, + vec.Vec2[f32]{200, 70}, vec.Vec2[f32]{400, 200}]! + } + b2 := Bezier{ + points: [b1.end(), b1.h3() + vec.Vec2[f32]{0, 2 * 80}, vec.Vec2[f32]{200, 70}, + b1.end() + vec.Vec2[f32]{400, 200}]! + } + + mut path := Path{} + + path.add(b1) + path.add(b2) + + assert sizeof(path) == 32772 +}