Skip to content

Commit

Permalink
cgen: fix aliased fixed array option fn call (fix #22927) (#22934)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 authored Nov 21, 2024
1 parent e384e74 commit 17f962d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
5 changes: 2 additions & 3 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -5791,7 +5791,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 {
Expand Down Expand Up @@ -7230,8 +7230,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()
Expand Down
43 changes: 43 additions & 0 deletions vlib/v/tests/aliases/aliased_fixed_array_option_fn_call_test.v
Original file line number Diff line number Diff line change
@@ -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]!
}

0 comments on commit 17f962d

Please sign in to comment.