Skip to content

Commit d1d47d6

Browse files
authored
cgen: fix codegen for nested selectorexpr on unwrapped option (fix #23406) (#23409)
1 parent 9fc8352 commit d1d47d6

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ mut:
158158
inside_for_c_stmt bool
159159
inside_cast_in_heap int // inside cast to interface type in heap (resolve recursive calls)
160160
inside_cast bool
161+
inside_selector bool
161162
inside_memset bool
162163
inside_const bool
163164
inside_array_item bool
@@ -4008,7 +4009,12 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
40084009
}
40094010
for i, typ in field.smartcasts {
40104011
if i == 0 && is_option_unwrap {
4011-
g.write('(*(${g.styp(typ)}*)')
4012+
deref := if g.inside_selector {
4013+
'*'.repeat(field.smartcasts.last().nr_muls() + 1)
4014+
} else {
4015+
'*'
4016+
}
4017+
g.write('(${deref}(${g.styp(typ)}*)')
40124018
}
40134019
g.write('(')
40144020
if field_sym.kind == .sum_type && !is_option {
@@ -4107,6 +4113,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
41074113
if field_is_opt {
41084114
g.write('((${g.base_type(field_typ)})')
41094115
}
4116+
old_inside_selector := g.inside_selector
4117+
g.inside_selector = node.expr is ast.SelectorExpr && node.expr.expr is ast.Ident
41104118
n_ptr := node.expr_type.nr_muls() - 1
41114119
if n_ptr > 0 {
41124120
g.write2('(', '*'.repeat(n_ptr))
@@ -4115,6 +4123,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
41154123
} else {
41164124
g.expr(node.expr)
41174125
}
4126+
g.inside_selector = old_inside_selector
41184127
if field_is_opt {
41194128
g.write(')')
41204129
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module main
2+
3+
interface IGameObject {
4+
mut:
5+
name string
6+
parent ?&IGameObject
7+
children []&IGameObject
8+
add_child(mut o IGameObject)
9+
advance()
10+
}
11+
12+
@[heap]
13+
struct GameObject implements IGameObject {
14+
mut:
15+
name string
16+
parent ?&IGameObject
17+
children []&IGameObject
18+
}
19+
20+
fn (mut gameobject GameObject) add_child(mut o IGameObject) {
21+
o.parent = &gameobject
22+
gameobject.children << o
23+
}
24+
25+
fn (mut gameobject GameObject) advance() {
26+
if gameobject.parent != none {
27+
eprintln('parent: ${gameobject.parent.name} ')
28+
}
29+
for mut child in gameobject.children {
30+
child.advance()
31+
}
32+
}
33+
34+
fn test_main() {
35+
mut v1 := &GameObject{
36+
name: 'v1'
37+
}
38+
mut v2 := &GameObject{
39+
name: 'v2'
40+
}
41+
v1.add_child(mut v2)
42+
v1.advance()
43+
assert true
44+
}

0 commit comments

Comments
 (0)