From 5c1662d234d8c884b8fba3828e9852f3967d7e6e Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 9 Nov 2025 13:56:35 -0300 Subject: [PATCH] cgen: fix codegen for if comptime and array fixed (fix #25691) (#25697) --- vlib/v/gen/c/comptime.v | 14 +++++++++++-- vlib/v/gen/c/consts_and_globals.v | 3 ++- .../tests/consts/const_if_fixed_array_test.v | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/consts/const_if_fixed_array_test.v diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index d905566cf..2388304ed 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -393,6 +393,7 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) { } tmp_var := g.new_tmp_var() is_opt_or_result := node.typ.has_option_or_result() + is_array_fixed := g.table.final_sym(node.typ).kind == .array_fixed line := if node.is_expr { stmt_str := g.go_before_last_stmt() g.write(util.tabs(g.indent)) @@ -485,10 +486,19 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) { g.skip_stmt_pos = true if is_opt_or_result { tmp_var2 := g.new_tmp_var() - g.write('{ ${g.base_type(node.typ)} ${tmp_var2} = ') + base_styp := g.base_type(node.typ) + g.write('{ ${base_styp} ${tmp_var2} = ') g.stmt(last) - g.writeln('builtin___result_ok(&(${g.base_type(node.typ)}[]) { ${tmp_var2} }, (_result*)(&${tmp_var}), sizeof(${g.base_type(node.typ)}));') + g.writeln('builtin___result_ok(&(${base_styp}[]) { ${tmp_var2} }, (_result*)(&${tmp_var}), sizeof(${base_styp}));') g.writeln('}') + } else if is_array_fixed { + base_styp := g.base_type(node.typ) + g.write('memcpy(&${tmp_var}, (${base_styp})') + g.stmt(last) + if g.out.last_n(2).contains(';') { + g.go_back(2) + } + g.write(', sizeof(${base_styp}))') } else { g.write('${tmp_var} = ') g.stmt(last) diff --git a/vlib/v/gen/c/consts_and_globals.v b/vlib/v/gen/c/consts_and_globals.v index d44f049eb..fc42934ab 100644 --- a/vlib/v/gen/c/consts_and_globals.v +++ b/vlib/v/gen/c/consts_and_globals.v @@ -319,7 +319,8 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, cname string, expr if surround_cbr { init.writeln('{') } - if expr is ast.ArrayInit && (expr as ast.ArrayInit).has_index { + if (expr is ast.ArrayInit && expr.has_index) + || (expr is ast.IfExpr && g.table.type_kind(expr.typ) == .array_fixed) { init.writeln(g.expr_string_surround('\tmemcpy(&${cname}, &', expr, ', sizeof(${styp}));')) } else if expr is ast.CallExpr && g.table.final_sym(g.unwrap_generic((expr as ast.CallExpr).return_type)).kind == .array_fixed { diff --git a/vlib/v/tests/consts/const_if_fixed_array_test.v b/vlib/v/tests/consts/const_if_fixed_array_test.v new file mode 100644 index 000000000..570b40ae6 --- /dev/null +++ b/vlib/v/tests/consts/const_if_fixed_array_test.v @@ -0,0 +1,21 @@ +// vtest vflags: -d some_other_define +pub const fixed_sized_comptime_array_const = $if some_other_define ? { + [u8(0x01), 0x02]! +} $else $if some_other_define_2 ? { + [u8(0x01), 0x02, 0x03]! +} $else { + [u8(0)]! +} + +pub const fixed_sized_comptime_array_const2 = $if some_other_define_2 ? { + [u8(0x01), 0x02, 0x03]! +} $else $if some_other_define ? { + [u8(0x01), 0x02]! +} $else { + [u8(0)]! +} + +fn test_main() { + assert fixed_sized_comptime_array_const == [u8(1), 2]! + assert fixed_sized_comptime_array_const2 == [u8(1), 2]! +} -- 2.39.5