Skip to content

Commit bed28d1

Browse files
authored
cgen: fix shared array slice (fix #23426) (#23427)
1 parent c92a21f commit bed28d1

File tree

5 files changed

+55
-6
lines changed

5 files changed

+55
-6
lines changed

vlib/v/checker/assign.v

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,10 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
378378
left_type = left_type.set_nr_muls(1)
379379
}
380380
} else if left_type.has_flag(.shared_f) {
381-
left_type = left_type.clear_flag(.shared_f).deref()
381+
left_type = left_type.clear_flag(.shared_f)
382+
if left_type.is_ptr() {
383+
left_type = left_type.deref()
384+
}
382385
}
383386
if ident_var_info.share == .atomic_t {
384387
left_type = left_type.set_flag(.atomic_f)

vlib/v/checker/checker.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5463,6 +5463,9 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
54635463
if c.fail_if_unreadable(expr.left, expr.left_type, what) {
54645464
return true
54655465
}
5466+
if typ.has_flag(.shared_f) && expr.left is ast.SelectorExpr {
5467+
return false
5468+
}
54665469
}
54675470
ast.InfixExpr {
54685471
pos = expr.left.pos().extend(expr.pos)

vlib/v/gen/c/cgen.v

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2928,7 +2928,9 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
29282928
g.write('&')
29292929
}
29302930
g.expr(expr)
2931-
g.write('->val')
2931+
if expr !is ast.IndexExpr {
2932+
g.write('->val')
2933+
}
29322934
return
29332935
}
29342936
if got_is_ptr && !expected_is_ptr && neither_void && exp_sym.kind != .placeholder

vlib/v/gen/c/index.v

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
6464
}
6565

6666
fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
67-
sym := g.table.final_sym(g.unwrap_generic(node.left_type))
67+
unwrapped_left_type := g.unwrap_generic(node.left_type)
68+
sym := g.table.final_sym(unwrapped_left_type)
6869
mut tmp_opt := ''
6970
mut cur_line := ''
7071
mut gen_or := node.or_expr.kind != .absent || node.is_option
72+
left_is_shared := unwrapped_left_type.has_flag(.shared_f)
7173
if sym.kind == .string {
7274
if node.is_gated {
7375
g.write('string_substr_ni(')
@@ -92,10 +94,16 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
9294
} else {
9395
g.write('array_slice(')
9496
}
97+
if left_is_shared {
98+
g.write('(')
99+
}
95100
if node.left_type.is_ptr() {
96101
g.write('*')
97102
}
98103
g.expr(node.left)
104+
if left_is_shared {
105+
g.write(').val')
106+
}
99107
} else if sym.info is ast.ArrayFixed {
100108
// Convert a fixed array to V array when doing `fixed_arr[start..end]`
101109
noscan := g.check_noscan(sym.info.elem_type)
@@ -107,6 +115,9 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
107115
g.write('new_array_from_c_array${noscan}(')
108116
ctype := g.styp(sym.info.elem_type)
109117
g.write('${sym.info.size}, ${sym.info.size}, sizeof(${ctype}), ')
118+
if left_is_shared {
119+
g.write('(')
120+
}
110121
if node.left_type.is_ptr() {
111122
g.write('*')
112123
}
@@ -118,11 +129,14 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
118129
g.write('${styp} ${var} = ')
119130
g.expr(node.left)
120131
g.writeln(';')
121-
g.write2(line, ' ${var})')
132+
g.write2(line, ' ${var}')
122133
} else {
123134
g.expr(node.left)
124-
g.write(')')
125135
}
136+
if left_is_shared {
137+
g.write(').val')
138+
}
139+
g.write(')')
126140
} else {
127141
g.expr(node.left)
128142
}
@@ -192,7 +206,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) {
192206
}
193207

194208
if left_is_shared {
195-
if left_is_ptr {
209+
if node.index !is ast.RangeExpr && left_is_ptr {
196210
g.write('->val')
197211
} else {
198212
g.write('.val')
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
struct Foo {
2+
pub mut:
3+
buf shared []u8 = []u8{len: 20, init: 6}
4+
buf2 shared [20]u8
5+
}
6+
7+
fn test_main() {
8+
mut foo := Foo{
9+
buf2: [20]u8{init: 5}
10+
}
11+
rlock foo.buf {
12+
if foo.buf.len > 0 {
13+
x := 10
14+
println('first ${x} bytes: ' + foo.buf[..x].str())
15+
sliced := foo.buf[..x]
16+
assert sliced == [u8(6), 6, 6, 6, 6, 6, 6, 6, 6, 6]
17+
} else {
18+
println('no data')
19+
assert false
20+
}
21+
}
22+
rlock foo.buf2 {
23+
x := 4
24+
println('first ${x} bytes: ' + foo.buf2[..x].str())
25+
assert foo.buf2[..x] == [u8(5), 5, 5, 5]
26+
}
27+
}

0 commit comments

Comments
 (0)