Skip to content

Commit

Permalink
cgen: fix codegen for array fixed on if and match expr (fix #23577, fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Feb 11, 2025
1 parent b5d6f40 commit 01096bc
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 2 deletions.
13 changes: 12 additions & 1 deletion vlib/v/gen/c/assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,13 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
} else {
g.write('{${styp} _ = ')
}
g.expr(val)
if val in [ast.MatchExpr, ast.IfExpr] && unaliased_right_sym.info is ast.ArrayFixed {
tmp_var := g.expr_with_var(val, var_type, false)
g.fixed_array_var_init(tmp_var, false, unaliased_right_sym.info.elem_type,
unaliased_right_sym.info.size)
} else {
g.expr(val)
}
g.writeln(';}')
}
} else if node.op == .assign && !g.pref.translated && (is_fixed_array_init
Expand Down Expand Up @@ -911,6 +917,11 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.array_init(val, c_name(ident.name))
} else if val_type.has_flag(.shared_f) {
g.expr_with_cast(val, val_type, var_type)
} else if val in [ast.MatchExpr, ast.IfExpr]
&& unaliased_right_sym.info is ast.ArrayFixed {
tmp_var := g.expr_with_var(val, var_type, false)
g.fixed_array_var_init(tmp_var, false, unaliased_right_sym.info.elem_type,
unaliased_right_sym.info.size)
} else {
g.expr(val)
}
Expand Down
17 changes: 16 additions & 1 deletion vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -2114,18 +2114,33 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
g.stmt(stmt)
}
} else {
mut is_array_fixed_init := false
mut ret_type := ast.void_type

g.set_current_pos_as_last_stmt_pos()
g.skip_stmt_pos = true
mut is_noreturn := false
if stmt in [ast.Return, ast.BranchStmt] {
is_noreturn = true
} else if stmt is ast.ExprStmt {
is_noreturn = is_noreturn_callexpr(stmt.expr)
if stmt.expr is ast.ArrayInit && stmt.expr.is_fixed {
is_array_fixed_init = true
ret_type = stmt.expr.typ
}
}
if !is_noreturn {
g.write('${tmp_var} = ')
if is_array_fixed_init {
g.write('memcpy(${tmp_var}, (${g.styp(ret_type)})')
} else {
g.write('${tmp_var} = ')
}
}
g.stmt(stmt)
if is_array_fixed_init {
lines := g.go_before_last_stmt().trim_right('; \n')
g.writeln('${lines}, sizeof(${tmp_var}));')
}
if !g.out.last_n(2).contains(';') {
g.writeln(';')
}
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/gen/c/if.v
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool {
if branch.stmts.len == 1 {
if branch.stmts[0] is ast.ExprStmt {
stmt := branch.stmts[0] as ast.ExprStmt
if stmt.expr is ast.ArrayInit && stmt.expr.is_fixed {
return true
}
if g.need_tmp_var_in_expr(stmt.expr) {
return true
}
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/gen/c/match.v
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool {
if branch.stmts.len == 1 {
if branch.stmts[0] is ast.ExprStmt {
stmt := branch.stmts[0] as ast.ExprStmt
if stmt.expr is ast.ArrayInit && stmt.expr.is_fixed {
return true
}
if g.need_tmp_var_in_expr(stmt.expr) {
return true
}
Expand Down
28 changes: 28 additions & 0 deletions vlib/v/tests/array_fixed_ternary_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
fn test_main() {
_ := if true { [0]! } else { [1]! }
_ := if true { [0] } else { [1] }

a := if true { [0]! } else { [1]! }
b := if true { [0] } else { [1] }
assert a.str() == '[0]'
assert b.str() == '[0]'
}

fn test_match() {
grid_size := 1

_ := match grid_size {
3 { ['Small', '3x3']! }
4 { ['Classic', '4x4']! }
5 { ['Big', '5x5']! }
else { ['Large', '6x6']! }
}

w := match grid_size {
3 { ['Small', '3x3']! }
4 { ['Classic', '4x4']! }
5 { ['Big', '5x5']! }
else { ['Large', '6x6']! }
}
assert w.str() == "['Large', '6x6']"
}

0 comments on commit 01096bc

Please sign in to comment.