From 8e85e4a8b2b0444267f1a5d0351013a527a4de38 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 21 Nov 2024 18:05:09 +0800 Subject: [PATCH] cgen: fix aliased fixed array option fn call --- vlib/v/gen/c/cgen.v | 5 +-- .../aliased_fixed_array_option_fn_call_test.v | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/aliases/aliased_fixed_array_option_fn_call_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index e7224f46bba43b..f0270febcfadda 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5790,7 +5790,7 @@ fn (mut g Gen) return_stmt(node ast.Return) { node.pos) } // normal return - return_sym := g.table.sym(g.unwrap_generic(node.types[0])) + return_sym := g.table.final_sym(g.unwrap_generic(node.types[0])) expr0 := node.exprs[0] // `return opt_ok(expr)` for functions that expect an option expr_type_is_opt := match expr0 { @@ -7229,8 +7229,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast mut is_array_fixed := false mut return_wrapped := false if is_option { - is_array_fixed = expr_stmt.expr in [ast.ArrayInit, ast.CastExpr] - && g.table.final_sym(return_type).kind == .array_fixed + is_array_fixed = g.table.final_sym(return_type).kind == .array_fixed if !is_array_fixed { if g.inside_return && !g.inside_struct_init && expr_stmt.expr is ast.CallExpr&& (expr_stmt.expr as ast.CallExpr).return_type.has_option_or_result() diff --git a/vlib/v/tests/aliases/aliased_fixed_array_option_fn_call_test.v b/vlib/v/tests/aliases/aliased_fixed_array_option_fn_call_test.v new file mode 100644 index 00000000000000..e1a3b89a33fe96 --- /dev/null +++ b/vlib/v/tests/aliases/aliased_fixed_array_option_fn_call_test.v @@ -0,0 +1,43 @@ +import encoding.binary + +pub type Addr = [4]u8 + +pub fn Addr.from_u32(a u32) Addr { + mut bytes := [4]u8{} + binary.big_endian_put_u32_fixed(mut bytes, a) + return Addr(bytes) +} + +pub fn (a Addr) u32() u32 { + return binary.big_endian_u32_fixed(a) +} + +struct Net { + netaddr Addr + broadcast Addr +} + +// returns Nth IP-address from the network if exists, else none +fn (n Net) nth(num i64) ?Addr { + mut addr := Addr{} + if num >= 0 { + addr = Addr.from_u32(n.netaddr.u32() + u32(num)) + } else { + addr = Addr.from_u32(n.broadcast.u32() + u32(num)) + } + if !(n.netaddr.u32() < addr.u32() && addr.u32() < n.broadcast.u32()) { + return none + } + return addr +} + +fn test_aliased_fixed_array_option_fn_call() { + net := Net{ + netaddr: Addr([u8(172), 16, 16, 0]!) + broadcast: Addr([u8(172), 16, 16, 3]!) + } + res1 := net.nth(1) or { panic(err) } + res2 := net.nth(1) or { Addr{} } + assert res1 == [u8(172), 16, 16, 1]! + assert res2 == [u8(172), 16, 16, 1]! +}