Skip to content

Commit f8f7c99

Browse files
authored
cgen: fix option ptr unwrapping (#21415)
1 parent 5667437 commit f8f7c99

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4901,7 +4901,7 @@ fn (mut g Gen) ident(node ast.Ident) {
49014901
g.write(g.get_ternary_name(name))
49024902
if is_auto_heap {
49034903
g.write('))')
4904-
if is_option {
4904+
if is_option && node.or_expr.kind != .absent {
49054905
g.write('.data')
49064906
}
49074907
}
@@ -6992,7 +6992,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
69926992
if g.fn_decl.return_type == ast.void_type {
69936993
g.writeln('\treturn;')
69946994
} else {
6995-
styp := g.typ(g.fn_decl.return_type)
6995+
styp := g.typ(g.fn_decl.return_type).replace('*', '_ptr')
69966996
err_obj := g.new_tmp_var()
69976997
g.writeln('\t${styp} ${err_obj};')
69986998
g.writeln('\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(_option));')

vlib/v/tests/option_ptr_unwrap_test.v

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import time
2+
// 41s.
3+
4+
struct Node[T] {
5+
mut:
6+
data T
7+
prev ?&Node[T]
8+
next ?&Node[T]
9+
}
10+
11+
struct LinkedList[T] {
12+
mut:
13+
size usize
14+
head ?&Node[T]
15+
}
16+
17+
fn new_linked_list[T]() &LinkedList[T] {
18+
return &LinkedList[T]{}
19+
}
20+
21+
fn (mut li LinkedList[T]) add[T](data T) {
22+
mut node := &Node[T]{data, none, none}
23+
24+
if li.head == none {
25+
li.head = node
26+
node.next = node
27+
node.prev = node
28+
} else {
29+
node.next = li.head
30+
node.prev = li.head?.prev
31+
node.prev?.next = node
32+
li.head?.prev = node
33+
}
34+
35+
li.size += 1
36+
}
37+
38+
fn (mut li LinkedList[T]) pop[T]() ?T {
39+
if li.head == none {
40+
return none
41+
}
42+
if li.size == 1 {
43+
data := li.head?.data
44+
li.head?.next = none
45+
li.head?.prev = none
46+
li.head = none
47+
li.size -= 1
48+
return data
49+
}
50+
51+
mut tail := li.head?.prev?
52+
mut curr := tail.prev?
53+
curr.next = li.head
54+
li.head?.prev = curr
55+
56+
tail.next = none
57+
tail.prev = none
58+
li.size -= 1
59+
60+
return tail.data
61+
}
62+
63+
@[heap]
64+
struct Integer {
65+
value int
66+
}
67+
68+
fn test_main() {
69+
max_itr := 2
70+
t := time.now()
71+
for itr in 0 .. max_itr {
72+
mut list := new_linked_list[&Integer]()
73+
println('Itr#${itr} list size: ${list.size}')
74+
75+
list.add(&Integer{10})
76+
println('Itr#${itr} list size: ${list.size}')
77+
list.add(&Integer{20})
78+
println('Itr#${itr} list size: ${list.size}')
79+
80+
mut n := list.pop()
81+
println('Itr#${itr} list size: ${list.size}, data: ${n?}')
82+
n = list.pop()
83+
println('Itr#${itr} list size: ${list.size}, data: ${n?}')
84+
n = list.pop()
85+
println('Itr#${itr} list size: ${list.size}, data: ${n}')
86+
}
87+
d := time.since(t)
88+
println('Bye(time ${d})!')
89+
}

0 commit comments

Comments
 (0)