From 5a017d91b49e9a505ac4dbc01f544d6bf73436be Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 18 Nov 2024 17:59:09 -0300 Subject: [PATCH 1/5] fix --- vlib/v/ast/ast.v | 20 +++++++++---------- vlib/v/checker/containers.v | 4 +++- vlib/v/gen/c/assign.v | 7 ++++--- vlib/v/gen/c/struct.v | 2 +- vlib/v/tests/aliases/alias_array_fixed_test.v | 10 ++++++++++ 5 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 vlib/v/tests/aliases/alias_array_fixed_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 90d7d992f84d85..f68dbff128d6f0 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1548,16 +1548,16 @@ pub: has_init bool has_index bool // true if temp variable index is used pub mut: - exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array - len_expr Expr // len: expr - cap_expr Expr // cap: expr - init_expr Expr // init: expr - expr_types []Type // [Dog, Cat] // also used for interface_types - elem_type Type // element type - init_type Type // init: value type - typ Type // array type - alias_type Type // alias type - has_callexpr bool // has expr which needs tmp var to initialize it + exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array + len_expr Expr // len: expr + cap_expr Expr // cap: expr + init_expr Expr // init: expr + expr_types []Type // [Dog, Cat] // also used for interface_types + elem_type Type // element type + init_type Type // init: value type + typ Type // array type + alias_type Type // alias type + has_tmp_var bool // has expr which needs tmp var to initialize it } pub struct ArrayDecompose { diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index 50137627160a9c..f2fe23b22bf1ee 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -164,7 +164,9 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { if ret_sym.kind == .array_fixed { typ = c.cast_fixed_array_ret(typ, ret_sym) } - node.has_callexpr = true + node.has_tmp_var = true + } else if expr is ast.CastExpr { + node.has_tmp_var = true } if typ == ast.void_type { c.error('invalid void array element type', expr.pos()) diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 80fb746ab49684..9e1126c4c23439 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -411,9 +411,10 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { unwrapped_val_type := g.unwrap_generic(val_type) right_sym := g.table.sym(unwrapped_val_type) unaliased_right_sym := g.table.final_sym(unwrapped_val_type) - is_fixed_array_var := unaliased_right_sym.kind == .array_fixed && val !is ast.ArrayInit - && (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr, ast.InfixExpr] - || (val is ast.CastExpr && val.expr !is ast.ArrayInit) + is_fixed_array_var := unaliased_right_sym.kind == .array_fixed && ( + (val is ast.ArrayInit && val.has_tmp_var) + || (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr, ast.InfixExpr]) + || (val is ast.CastExpr && (val.expr !is ast.ArrayInit|| (val.expr is ast.ArrayInit && val.expr.has_tmp_var))) || (val is ast.PrefixExpr && val.op == .arrow) || (val is ast.UnsafeExpr && val.expr in [ast.SelectorExpr, ast.Ident])) && !g.pref.translated diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index d85666c7baa9e1..e1b84d8a1a6e6e 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -697,7 +697,7 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type) g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size) - } else if sfield.expr.has_callexpr { + } else if sfield.expr.has_tmp_var { tmp_var := g.expr_with_fixed_array(sfield.expr, sfield.typ, sfield.expected_type) g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size) diff --git a/vlib/v/tests/aliases/alias_array_fixed_test.v b/vlib/v/tests/aliases/alias_array_fixed_test.v new file mode 100644 index 00000000000000..a21a5107e3c0b5 --- /dev/null +++ b/vlib/v/tests/aliases/alias_array_fixed_test.v @@ -0,0 +1,10 @@ +module main + +type Arr = [4]u8 + +fn test_main() { + mut a := Arr{} + a = Arr([u8(5), 4, 3, 2]!) + assert a == Arr([u8(5), 4, 3, 2]!) + assert a == [u8(5), 4, 3, 2]! +} From 312c3b22ca4e5c8966b3d53f91d09fa0caa28b70 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 18 Nov 2024 18:02:14 -0300 Subject: [PATCH 2/5] fix --- vlib/v/gen/c/assign.v | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 9e1126c4c23439..133e179ab3de60 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -411,13 +411,12 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { unwrapped_val_type := g.unwrap_generic(val_type) right_sym := g.table.sym(unwrapped_val_type) unaliased_right_sym := g.table.final_sym(unwrapped_val_type) - is_fixed_array_var := unaliased_right_sym.kind == .array_fixed && ( + is_fixed_array_var := !g.pref.translated && unaliased_right_sym.kind == .array_fixed && ( (val is ast.ArrayInit && val.has_tmp_var) || (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr, ast.InfixExpr]) || (val is ast.CastExpr && (val.expr !is ast.ArrayInit|| (val.expr is ast.ArrayInit && val.expr.has_tmp_var))) || (val is ast.PrefixExpr && val.op == .arrow) || (val is ast.UnsafeExpr && val.expr in [ast.SelectorExpr, ast.Ident])) - && !g.pref.translated g.is_assign_lhs = true g.assign_op = node.op From df252dbb2b60a55c297e5896f0b18b1ec492b0f6 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 18 Nov 2024 18:05:17 -0300 Subject: [PATCH 3/5] fix --- vlib/v/gen/c/assign.v | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 133e179ab3de60..7052371b9cc283 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -411,10 +411,11 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { unwrapped_val_type := g.unwrap_generic(val_type) right_sym := g.table.sym(unwrapped_val_type) unaliased_right_sym := g.table.final_sym(unwrapped_val_type) - is_fixed_array_var := !g.pref.translated && unaliased_right_sym.kind == .array_fixed && ( - (val is ast.ArrayInit && val.has_tmp_var) - || (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr, ast.InfixExpr]) - || (val is ast.CastExpr && (val.expr !is ast.ArrayInit|| (val.expr is ast.ArrayInit && val.expr.has_tmp_var))) + is_fixed_array_var := !g.pref.translated && unaliased_right_sym.kind == .array_fixed + && val !is ast.ArrayInit + && (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr, ast.InfixExpr] + || (val is ast.CastExpr && (val.expr !is ast.ArrayInit + || (val.expr is ast.ArrayInit && val.expr.has_tmp_var))) || (val is ast.PrefixExpr && val.op == .arrow) || (val is ast.UnsafeExpr && val.expr in [ast.SelectorExpr, ast.Ident])) g.is_assign_lhs = true From 4d564aad48421102ac24deb5eda728fbcaa86335 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 18 Nov 2024 21:38:36 -0300 Subject: [PATCH 4/5] fix --- vlib/v/checker/containers.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index f2fe23b22bf1ee..a429ad3802ae89 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -165,8 +165,8 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { typ = c.cast_fixed_array_ret(typ, ret_sym) } node.has_tmp_var = true - } else if expr is ast.CastExpr { - node.has_tmp_var = true + } else if !node.has_tmp_var && mut expr is ast.CastExpr { + node.has_tmp_var = expr.expr is ast.ArrayInit && expr.expr.has_tmp_var } if typ == ast.void_type { c.error('invalid void array element type', expr.pos()) From f453614711a24594f4045f4d0ee83e1a2ae4b6d5 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 18 Nov 2024 22:46:03 -0300 Subject: [PATCH 5/5] fix --- vlib/v/ast/ast.v | 20 ++++++++++---------- vlib/v/checker/containers.v | 4 +--- vlib/v/gen/c/assign.v | 13 +++++++++---- vlib/v/gen/c/struct.v | 2 +- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index f68dbff128d6f0..90d7d992f84d85 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1548,16 +1548,16 @@ pub: has_init bool has_index bool // true if temp variable index is used pub mut: - exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array - len_expr Expr // len: expr - cap_expr Expr // cap: expr - init_expr Expr // init: expr - expr_types []Type // [Dog, Cat] // also used for interface_types - elem_type Type // element type - init_type Type // init: value type - typ Type // array type - alias_type Type // alias type - has_tmp_var bool // has expr which needs tmp var to initialize it + exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array + len_expr Expr // len: expr + cap_expr Expr // cap: expr + init_expr Expr // init: expr + expr_types []Type // [Dog, Cat] // also used for interface_types + elem_type Type // element type + init_type Type // init: value type + typ Type // array type + alias_type Type // alias type + has_callexpr bool // has expr which needs tmp var to initialize it } pub struct ArrayDecompose { diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index a429ad3802ae89..50137627160a9c 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -164,9 +164,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { if ret_sym.kind == .array_fixed { typ = c.cast_fixed_array_ret(typ, ret_sym) } - node.has_tmp_var = true - } else if !node.has_tmp_var && mut expr is ast.CastExpr { - node.has_tmp_var = expr.expr is ast.ArrayInit && expr.expr.has_tmp_var + node.has_callexpr = true } if typ == ast.void_type { c.error('invalid void array element type', expr.pos()) diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 7052371b9cc283..910cf4a17b11c4 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -414,8 +414,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { is_fixed_array_var := !g.pref.translated && unaliased_right_sym.kind == .array_fixed && val !is ast.ArrayInit && (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr, ast.InfixExpr] - || (val is ast.CastExpr && (val.expr !is ast.ArrayInit - || (val.expr is ast.ArrayInit && val.expr.has_tmp_var))) + || (val is ast.CastExpr && val.expr !is ast.ArrayInit) || (val is ast.PrefixExpr && val.op == .arrow) || (val is ast.UnsafeExpr && val.expr in [ast.SelectorExpr, ast.Ident])) g.is_assign_lhs = true @@ -451,13 +450,19 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { g.expr(val) g.writeln(';}') } - } else if node.op == .assign && !g.pref.translated - && (is_fixed_array_init || (right_sym.kind == .array_fixed && val is ast.Ident)) { + } else if node.op == .assign && !g.pref.translated && (is_fixed_array_init + || (unaliased_right_sym.kind == .array_fixed && val in [ast.Ident, ast.CastExpr])) { // Fixed arrays if is_fixed_array_init && var_type.has_flag(.option) { g.expr(left) g.write(' = ') g.expr_with_opt(val, val_type, var_type) + } else if unaliased_right_sym.kind == .array_fixed && val is ast.CastExpr { + g.write('memcpy(') + g.expr(left) + g.write(', ') + g.expr(val) + g.writeln(', sizeof(${g.styp(var_type)}));') } else { mut v_var := '' arr_typ := styp.trim('*') diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index e1b84d8a1a6e6e..d85666c7baa9e1 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -697,7 +697,7 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type) g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size) - } else if sfield.expr.has_tmp_var { + } else if sfield.expr.has_callexpr { tmp_var := g.expr_with_fixed_array(sfield.expr, sfield.typ, sfield.expected_type) g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size)