cgen: fix shared array slice (fix #23426) (#23427)

This commit is contained in:
Felipe Pena 2025-01-11 06:44:33 -03:00 committed by GitHub
parent c92a21f8a5
commit bed28d1e8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 55 additions and 6 deletions

View File

@ -378,7 +378,10 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
left_type = left_type.set_nr_muls(1) left_type = left_type.set_nr_muls(1)
} }
} else if left_type.has_flag(.shared_f) { } else if left_type.has_flag(.shared_f) {
left_type = left_type.clear_flag(.shared_f).deref() left_type = left_type.clear_flag(.shared_f)
if left_type.is_ptr() {
left_type = left_type.deref()
}
} }
if ident_var_info.share == .atomic_t { if ident_var_info.share == .atomic_t {
left_type = left_type.set_flag(.atomic_f) left_type = left_type.set_flag(.atomic_f)

View File

@ -5463,6 +5463,9 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
if c.fail_if_unreadable(expr.left, expr.left_type, what) { if c.fail_if_unreadable(expr.left, expr.left_type, what) {
return true return true
} }
if typ.has_flag(.shared_f) && expr.left is ast.SelectorExpr {
return false
}
} }
ast.InfixExpr { ast.InfixExpr {
pos = expr.left.pos().extend(expr.pos) pos = expr.left.pos().extend(expr.pos)

View File

@ -2928,7 +2928,9 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
g.write('&') g.write('&')
} }
g.expr(expr) g.expr(expr)
g.write('->val') if expr !is ast.IndexExpr {
g.write('->val')
}
return return
} }
if got_is_ptr && !expected_is_ptr && neither_void && exp_sym.kind != .placeholder if got_is_ptr && !expected_is_ptr && neither_void && exp_sym.kind != .placeholder

View File

@ -64,10 +64,12 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
} }
fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) { fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
sym := g.table.final_sym(g.unwrap_generic(node.left_type)) unwrapped_left_type := g.unwrap_generic(node.left_type)
sym := g.table.final_sym(unwrapped_left_type)
mut tmp_opt := '' mut tmp_opt := ''
mut cur_line := '' mut cur_line := ''
mut gen_or := node.or_expr.kind != .absent || node.is_option mut gen_or := node.or_expr.kind != .absent || node.is_option
left_is_shared := unwrapped_left_type.has_flag(.shared_f)
if sym.kind == .string { if sym.kind == .string {
if node.is_gated { if node.is_gated {
g.write('string_substr_ni(') g.write('string_substr_ni(')
@ -92,10 +94,16 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
} else { } else {
g.write('array_slice(') g.write('array_slice(')
} }
if left_is_shared {
g.write('(')
}
if node.left_type.is_ptr() { if node.left_type.is_ptr() {
g.write('*') g.write('*')
} }
g.expr(node.left) g.expr(node.left)
if left_is_shared {
g.write(').val')
}
} else if sym.info is ast.ArrayFixed { } else if sym.info is ast.ArrayFixed {
// Convert a fixed array to V array when doing `fixed_arr[start..end]` // Convert a fixed array to V array when doing `fixed_arr[start..end]`
noscan := g.check_noscan(sym.info.elem_type) 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) {
g.write('new_array_from_c_array${noscan}(') g.write('new_array_from_c_array${noscan}(')
ctype := g.styp(sym.info.elem_type) ctype := g.styp(sym.info.elem_type)
g.write('${sym.info.size}, ${sym.info.size}, sizeof(${ctype}), ') g.write('${sym.info.size}, ${sym.info.size}, sizeof(${ctype}), ')
if left_is_shared {
g.write('(')
}
if node.left_type.is_ptr() { if node.left_type.is_ptr() {
g.write('*') g.write('*')
} }
@ -118,11 +129,14 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
g.write('${styp} ${var} = ') g.write('${styp} ${var} = ')
g.expr(node.left) g.expr(node.left)
g.writeln(';') g.writeln(';')
g.write2(line, ' ${var})') g.write2(line, ' ${var}')
} else { } else {
g.expr(node.left) g.expr(node.left)
g.write(')')
} }
if left_is_shared {
g.write(').val')
}
g.write(')')
} else { } else {
g.expr(node.left) g.expr(node.left)
} }
@ -192,7 +206,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) {
} }
if left_is_shared { if left_is_shared {
if left_is_ptr { if node.index !is ast.RangeExpr && left_is_ptr {
g.write('->val') g.write('->val')
} else { } else {
g.write('.val') g.write('.val')

View File

@ -0,0 +1,27 @@
struct Foo {
pub mut:
buf shared []u8 = []u8{len: 20, init: 6}
buf2 shared [20]u8
}
fn test_main() {
mut foo := Foo{
buf2: [20]u8{init: 5}
}
rlock foo.buf {
if foo.buf.len > 0 {
x := 10
println('first ${x} bytes: ' + foo.buf[..x].str())
sliced := foo.buf[..x]
assert sliced == [u8(6), 6, 6, 6, 6, 6, 6, 6, 6, 6]
} else {
println('no data')
assert false
}
}
rlock foo.buf2 {
x := 4
println('first ${x} bytes: ' + foo.buf2[..x].str())
assert foo.buf2[..x] == [u8(5), 5, 5, 5]
}
}