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.