vlang

/

v Public
0 commits 39 issues 0 pull requests 0 contributors Discussions Projects CI

cgen: fixed-array if/match return with mixed fn-call + literal branches emits broken C (void * mismatch) #7

Description

A fixed-array if/match expression used as a return value generates broken C when the branches mix a function call (whose fixed-array return uses the .ret_arr wrapper struct) with a fixed-array literal ([..]!, a raw C array). cgen emits a memcpy that passes the wrapper struct where a void * is expected.

When all branches are literals, or all branches are function calls, it compiles fine — only the mix breaks (for both if and match).

V version: V 0.5.1, current master (927a1e258) OS/Backend: reproduced on macOS arm64; originally reported on macOS/cc.

Reproducer

fn fa() [3]int {
    return [1, 2, 3]!
}

fn ret_if(c bool) [3]int {
    return if c { fa() } else { [9, 9, 9]! }
}

fn main() {
    println(ret_if(true))
}

The same fails with match:

fn ret_match(n int) [3]int {
    return match n {
        0 { fa() }
        else { [7, 7, 7]! }
    }
}

Compile with:

v file.v

Current behavior

error: passing '_v_Array_fixed_int_3' (aka 'struct _v_Array_fixed_int_3') to parameter of incompatible type 'void *'
  memcpy(_t2, (Array_fixed_int_3){9, 9, 9}, sizeof(_t2));

The function-call branch produces fa().ret_arr (raw array via the return wrapper) while the literal branch produces the _v_Array_fixed_int_3 struct, and the two are handled inconsistently in the if/match-return codegen.

Isolation

  • return if c { fa() } else { fb() } (both function calls) — compiles cleanly.
  • return if c { [1,2,3]! } else { [9,9,9]! } (both literals) — compiles cleanly.
  • Only a branch mix (one call + one literal) triggers it; same for match.This is distinct from the already-fixed #27350 (fixed array return via local) and #27360 (fixed array expression field assignment).

Notes

  • Reported via the bugs.vlang.io crash reporter.
    [!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.