Skip to content

Commit 01096bc

Browse files
authored
cgen: fix codegen for array fixed on if and match expr (fix #23577, fix #23589) (#23682)
1 parent b5d6f40 commit 01096bc

5 files changed

Lines changed: 62 additions & 2 deletions

File tree

‎vlib/v/gen/c/assign.v‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,13 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
526526
} else {
527527
g.write('{${styp} _ = ')
528528
}
529-
g.expr(val)
529+
if val in [ast.MatchExpr, ast.IfExpr] && unaliased_right_sym.info is ast.ArrayFixed {
530+
tmp_var := g.expr_with_var(val, var_type, false)
531+
g.fixed_array_var_init(tmp_var, false, unaliased_right_sym.info.elem_type,
532+
unaliased_right_sym.info.size)
533+
} else {
534+
g.expr(val)
535+
}
530536
g.writeln(';}')
531537
}
532538
} else if node.op == .assign && !g.pref.translated && (is_fixed_array_init
@@ -911,6 +917,11 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
911917
g.array_init(val, c_name(ident.name))
912918
} else if val_type.has_flag(.shared_f) {
913919
g.expr_with_cast(val, val_type, var_type)
920+
} else if val in [ast.MatchExpr, ast.IfExpr]
921+
&& unaliased_right_sym.info is ast.ArrayFixed {
922+
tmp_var := g.expr_with_var(val, var_type, false)
923+
g.fixed_array_var_init(tmp_var, false, unaliased_right_sym.info.elem_type,
924+
unaliased_right_sym.info.size)
914925
} else {
915926
g.expr(val)
916927
}

‎vlib/v/gen/c/cgen.v‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2114,18 +2114,33 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
21142114
g.stmt(stmt)
21152115
}
21162116
} else {
2117+
mut is_array_fixed_init := false
2118+
mut ret_type := ast.void_type
2119+
21172120
g.set_current_pos_as_last_stmt_pos()
21182121
g.skip_stmt_pos = true
21192122
mut is_noreturn := false
21202123
if stmt in [ast.Return, ast.BranchStmt] {
21212124
is_noreturn = true
21222125
} else if stmt is ast.ExprStmt {
21232126
is_noreturn = is_noreturn_callexpr(stmt.expr)
2127+
if stmt.expr is ast.ArrayInit && stmt.expr.is_fixed {
2128+
is_array_fixed_init = true
2129+
ret_type = stmt.expr.typ
2130+
}
21242131
}
21252132
if !is_noreturn {
2126-
g.write('${tmp_var} = ')
2133+
if is_array_fixed_init {
2134+
g.write('memcpy(${tmp_var}, (${g.styp(ret_type)})')
2135+
} else {
2136+
g.write('${tmp_var} = ')
2137+
}
21272138
}
21282139
g.stmt(stmt)
2140+
if is_array_fixed_init {
2141+
lines := g.go_before_last_stmt().trim_right('; \n')
2142+
g.writeln('${lines}, sizeof(${tmp_var}));')
2143+
}
21292144
if !g.out.last_n(2).contains(';') {
21302145
g.writeln(';')
21312146
}

‎vlib/v/gen/c/if.v‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool {
2020
if branch.stmts.len == 1 {
2121
if branch.stmts[0] is ast.ExprStmt {
2222
stmt := branch.stmts[0] as ast.ExprStmt
23+
if stmt.expr is ast.ArrayInit && stmt.expr.is_fixed {
24+
return true
25+
}
2326
if g.need_tmp_var_in_expr(stmt.expr) {
2427
return true
2528
}

‎vlib/v/gen/c/match.v‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool {
2525
if branch.stmts.len == 1 {
2626
if branch.stmts[0] is ast.ExprStmt {
2727
stmt := branch.stmts[0] as ast.ExprStmt
28+
if stmt.expr is ast.ArrayInit && stmt.expr.is_fixed {
29+
return true
30+
}
2831
if g.need_tmp_var_in_expr(stmt.expr) {
2932
return true
3033
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
fn test_main() {
2+
_ := if true { [0]! } else { [1]! }
3+
_ := if true { [0] } else { [1] }
4+
5+
a := if true { [0]! } else { [1]! }
6+
b := if true { [0] } else { [1] }
7+
assert a.str() == '[0]'
8+
assert b.str() == '[0]'
9+
}
10+
11+
fn test_match() {
12+
grid_size := 1
13+
14+
_ := match grid_size {
15+
3 { ['Small', '3x3']! }
16+
4 { ['Classic', '4x4']! }
17+
5 { ['Big', '5x5']! }
18+
else { ['Large', '6x6']! }
19+
}
20+
21+
w := match grid_size {
22+
3 { ['Small', '3x3']! }
23+
4 { ['Classic', '4x4']! }
24+
5 { ['Big', '5x5']! }
25+
else { ['Large', '6x6']! }
26+
}
27+
assert w.str() == "['Large', '6x6']"
28+
}

0 commit comments

Comments
 (0)