From 7b20c9c6fb1ffa45ddd0945fd34a9f9e3fd422e5 Mon Sep 17 00:00:00 2001 From: Jesus Alvarez Date: Sun, 25 Jan 2026 22:58:56 -0800 Subject: [PATCH] cgen: fix or-block with fixed array constants with GCC 15.2 (fix #26442) (#26443) --- vlib/v/gen/c/cgen.v | 14 ++++++++++++- .../options/option_fixed_arr_const_test.v | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/options/option_fixed_arr_const_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index d70e0877d..e47641aa9 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -7404,7 +7404,19 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast g.write('${cvar_name} = ') } if is_array_fixed { - g.write('memcpy(${cvar_name}${tmp_op}data, (${cast_typ})') + // For fixed arrays, we need memcpy. Use compound literal cast only for + // expressions that generate brace-enclosed initializers (which need + // to become compound literals), not for constants/variables where + // casting to array type is invalid C. + is_array_init := expr_stmt.expr is ast.ArrayInit + || expr_stmt.expr is ast.StructInit + || (expr_stmt.expr is ast.CastExpr + && (expr_stmt.expr as ast.CastExpr).expr is ast.ArrayInit) + if is_array_init { + g.write('memcpy(${cvar_name}${tmp_op}data, (${cast_typ})') + } else { + g.write('memcpy(${cvar_name}${tmp_op}data, ') + } } // return expr or { fn_returns_option() } if is_option && g.inside_return && expr_stmt.expr is ast.CallExpr diff --git a/vlib/v/tests/options/option_fixed_arr_const_test.v b/vlib/v/tests/options/option_fixed_arr_const_test.v new file mode 100644 index 000000000..33e84d71f --- /dev/null +++ b/vlib/v/tests/options/option_fixed_arr_const_test.v @@ -0,0 +1,20 @@ +// Test for or-block returning a fixed array constant. +// Regression test for issue where cgen generated invalid C cast to array type. +const default_arr = [f32(1.0), 2.0, 3.0, 4.0]! + +fn get_arr(key string) ?[4]f32 { + if key == 'valid' { + return [f32(0.1), 0.2, 0.3, 0.4]! + } + return none +} + +fn test_or_block_with_fixed_array_const() { + result := get_arr('invalid') or { default_arr } + assert result == default_arr +} + +fn test_or_block_with_valid_key() { + result := get_arr('valid') or { default_arr } + assert result == [f32(0.1), 0.2, 0.3, 0.4]! +} -- 2.39.5