From d3b5dbd58cca4b7dd538d0bc866df7d77c493083 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Tue, 3 Dec 2024 06:22:31 -0300 Subject: [PATCH] cgen: fix update expr with embed fixed array with multiple dimensions (fix #23048) (#23049) --- vlib/v/gen/c/array.v | 26 ++++------- vlib/v/gen/c/struct.v | 33 ++++++++------ vlib/v/tests/fixed_array_2_dims_embed_test.v | 48 ++++++++++++++++++++ 3 files changed, 75 insertions(+), 32 deletions(-) create mode 100644 vlib/v/tests/fixed_array_2_dims_embed_test.v diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 982a46858..4130bcc56 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -1657,12 +1657,17 @@ fn (mut g Gen) fixed_array_update_expr_field(expr_str string, field_type ast.Typ g.write('}') } } + embed_field := if is_update_embed { + g.get_embed_field_name(field_type, field_name) + } else { + '' + } for i in 0 .. size { if elem_sym.info is ast.ArrayFixed { init_str := if g.inside_array_fixed_struct { '${expr_str}' } else { - '${expr_str}->${c_name(field_name)}[${i}]' + '${expr_str}->${embed_field}${c_name(field_name)}[${i}]' } g.fixed_array_update_expr_field(init_str, field_type, field_name, is_auto_deref, elem_sym.info.elem_type, elem_sym.info.size, is_update_embed) @@ -1675,26 +1680,11 @@ fn (mut g Gen) fixed_array_update_expr_field(expr_str string, field_type ast.Typ g.write('.') } if is_update_embed { - update_sym := g.table.sym(field_type) - _, embeds := g.table.find_field_from_embeds(update_sym, field_name) or { - ast.StructField{}, []ast.Type{} - } - for embed in embeds { - esym := g.table.sym(embed) - ename := esym.embed_name() - g.write(ename) - if embed.is_ptr() { - g.write('->') - } else { - g.write('.') - } - } + g.write(embed_field) } g.write(c_name(field_name)) } - if !expr_str.starts_with('(') && !expr_str.starts_with('{') { - g.write('[${i}]') - } + g.write('[${i}]') } if i != size - 1 { g.write(', ') diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index 9a1d66637..5934f6495 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -326,20 +326,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) { g.write('.') } if node.is_update_embed { - update_sym := g.table.sym(node.update_expr_type) - _, embeds := g.table.find_field_from_embeds(update_sym, field.name) or { - ast.StructField{}, []ast.Type{} - } - for embed in embeds { - esym := g.table.sym(embed) - ename := esym.embed_name() - g.write(ename) - if embed.is_ptr() { - g.write('->') - } else { - g.write('.') - } - } + g.write(g.get_embed_field_name(node.update_expr_type, field.name)) } g.write(c_name(field.name)) } @@ -402,6 +389,24 @@ fn (mut g Gen) struct_init(node ast.StructInit) { } } +fn (mut g Gen) get_embed_field_name(field_type ast.Type, field_name string) string { + update_sym := g.table.sym(field_type) + _, embeds := g.table.find_field_from_embeds(update_sym, field_name) or { + ast.StructField{}, []ast.Type{} + } + mut s := '' + for embed in embeds { + esym := g.table.sym(embed) + ename := esym.embed_name() + if embed.is_ptr() { + s += '${ename}->' + } else { + s += '${ename}.' + } + } + return s +} + fn (mut g Gen) zero_struct_field(field ast.StructField) bool { old_inside_cast_in_heap := g.inside_cast_in_heap g.inside_cast_in_heap = 0 diff --git a/vlib/v/tests/fixed_array_2_dims_embed_test.v b/vlib/v/tests/fixed_array_2_dims_embed_test.v new file mode 100644 index 000000000..8944a3ca5 --- /dev/null +++ b/vlib/v/tests/fixed_array_2_dims_embed_test.v @@ -0,0 +1,48 @@ +module main + +type Mat4 = [16]f32 +type Mat14 = [1][16]f32 + +@[heap] +struct GameObject { +mut: + transform Mat4 + transform2 Mat14 +} + +@[heap] +struct Ship { + GameObject +} + +fn Ship.new() &Ship { + mut ship := &Ship{} + return ship +} + +fn (mut ship Ship) clone() &Ship { + return &Ship{ + ...ship + } +} + +fn test_main() { + mut v1 := Ship.new() + v1.transform[0] = 1.0 + v1.transform[15] = 2.0 + v1.transform2[0][0] = 1.0 + v1.transform2[0][15] = 2.0 + mut v2 := v1.clone() + eprintln('v1=${v1.transform}\nv2=${v2.transform}') + assert v1.transform == v2.transform + assert v1.transform2 == v2.transform2 + assert v1.transform[0] == 1.0 + assert v2.transform[0] == 1.0 + assert v1.transform[15] == 2.0 + assert v2.transform[15] == 2.0 + + assert v1.transform2[0][0] == 1.0 + assert v2.transform2[0][0] == 1.0 + assert v1.transform2[0][15] == 2.0 + assert v2.transform2[0][15] == 2.0 +} -- 2.39.5