Skip to content

Commit e3d3863

Browse files
authored
cgen: refactor need_tmp_var_in_expr/match() (fix #15675) (#15676)
1 parent 862d91e commit e3d3863

File tree

3 files changed

+87
-28
lines changed

3 files changed

+87
-28
lines changed

vlib/v/gen/c/if.v

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,42 +31,91 @@ fn (mut g Gen) need_tmp_var_in_expr(expr ast.Expr) bool {
3131
if is_noreturn_callexpr(expr) {
3232
return true
3333
}
34-
if expr is ast.MatchExpr {
35-
return true
36-
}
37-
if expr is ast.CallExpr {
38-
if expr.is_method {
39-
left_sym := g.table.sym(expr.receiver_type)
40-
if left_sym.kind in [.array, .array_fixed, .map] {
34+
match expr {
35+
ast.IfExpr {
36+
if g.need_tmp_var_in_if(expr) {
4137
return true
4238
}
4339
}
44-
if expr.or_block.kind != .absent {
40+
ast.MatchExpr {
4541
return true
4642
}
47-
}
48-
if expr is ast.CastExpr {
49-
return g.need_tmp_var_in_expr(expr.expr)
50-
}
51-
if expr is ast.ParExpr {
52-
return g.need_tmp_var_in_expr(expr.expr)
53-
}
54-
if expr is ast.ConcatExpr {
55-
for val in expr.vals {
56-
if val is ast.CallExpr {
57-
if val.return_type.has_flag(.optional) {
43+
ast.CallExpr {
44+
if expr.is_method {
45+
left_sym := g.table.sym(expr.receiver_type)
46+
if left_sym.kind in [.array, .array_fixed, .map] {
5847
return true
5948
}
6049
}
50+
if expr.or_block.kind != .absent {
51+
return true
52+
}
6153
}
62-
}
63-
if expr is ast.IndexExpr {
64-
if expr.or_expr.kind != .absent {
65-
return true
54+
ast.CastExpr {
55+
return g.need_tmp_var_in_expr(expr.expr)
6656
}
67-
if g.need_tmp_var_in_expr(expr.index) {
68-
return true
57+
ast.ParExpr {
58+
return g.need_tmp_var_in_expr(expr.expr)
59+
}
60+
ast.ConcatExpr {
61+
for val in expr.vals {
62+
if val is ast.CallExpr {
63+
if val.return_type.has_flag(.optional) {
64+
return true
65+
}
66+
}
67+
}
68+
}
69+
ast.IndexExpr {
70+
if expr.or_expr.kind != .absent {
71+
return true
72+
}
73+
if g.need_tmp_var_in_expr(expr.index) {
74+
return true
75+
}
76+
}
77+
ast.ArrayInit {
78+
if g.need_tmp_var_in_expr(expr.len_expr) {
79+
return true
80+
}
81+
if g.need_tmp_var_in_expr(expr.cap_expr) {
82+
return true
83+
}
84+
if g.need_tmp_var_in_expr(expr.default_expr) {
85+
return true
86+
}
87+
for elem_expr in expr.exprs {
88+
if g.need_tmp_var_in_expr(elem_expr) {
89+
return true
90+
}
91+
}
92+
}
93+
ast.MapInit {
94+
for key in expr.keys {
95+
if g.need_tmp_var_in_expr(key) {
96+
return true
97+
}
98+
}
99+
for val in expr.vals {
100+
if g.need_tmp_var_in_expr(val) {
101+
return true
102+
}
103+
}
104+
}
105+
ast.StructInit {
106+
if g.need_tmp_var_in_expr(expr.update_expr) {
107+
return true
108+
}
109+
for field in expr.fields {
110+
if g.need_tmp_var_in_expr(field.expr) {
111+
return true
112+
}
113+
}
114+
}
115+
ast.SelectorExpr {
116+
return g.need_tmp_var_in_expr(expr.expr)
69117
}
118+
else {}
70119
}
71120
return false
72121
}

vlib/v/gen/c/match.v

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool {
2828
if branch.stmts.len == 1 {
2929
if branch.stmts[0] is ast.ExprStmt {
3030
stmt := branch.stmts[0] as ast.ExprStmt
31-
if stmt.expr in [ast.CallExpr, ast.IfExpr, ast.MatchExpr, ast.StructInit]
32-
|| (stmt.expr is ast.IndexExpr
33-
&& (stmt.expr as ast.IndexExpr).or_expr.kind != .absent) {
31+
if g.need_tmp_var_in_expr(stmt.expr) {
3432
return true
3533
}
3634
}

vlib/v/tests/if_expr_with_index_expr_test.v

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,15 @@ fn test_if_expr_with_index_expr() {
77
println(b)
88
assert true
99
}
10+
11+
struct Foo {
12+
name string
13+
}
14+
15+
fn test_if_expr_with_selector_expr() {
16+
a := [Foo{'abc1'}, Foo{'abc2'}, Foo{'abc3'}]
17+
18+
b := if true { a[rand.intn(a.len) or { 0 }].name } else { 'not found' }
19+
println(b)
20+
assert true
21+
}

0 commit comments

Comments
 (0)