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)
}
} 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 {
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) {
return true
}
if typ.has_flag(.shared_f) && expr.left is ast.SelectorExpr {
return false
}
}
ast.InfixExpr {
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.expr(expr)
g.write('->val')
if expr !is ast.IndexExpr {
g.write('->val')
}
return
}
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) {
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 cur_line := ''
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 node.is_gated {
g.write('string_substr_ni(')
@ -92,10 +94,16 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
} else {
g.write('array_slice(')
}
if left_is_shared {
g.write('(')
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
if left_is_shared {
g.write(').val')
}
} else if sym.info is ast.ArrayFixed {
// Convert a fixed array to V array when doing `fixed_arr[start..end]`
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}(')
ctype := g.styp(sym.info.elem_type)
g.write('${sym.info.size}, ${sym.info.size}, sizeof(${ctype}), ')
if left_is_shared {
g.write('(')
}
if node.left_type.is_ptr() {
g.write('*')
}
@ -118,11 +129,14 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
g.write('${styp} ${var} = ')
g.expr(node.left)
g.writeln(';')
g.write2(line, ' ${var})')
g.write2(line, ' ${var}')
} else {
g.expr(node.left)
g.write(')')
}
if left_is_shared {
g.write(').val')
}
g.write(')')
} else {
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_ptr {
if node.index !is ast.RangeExpr && left_is_ptr {
g.write('->val')
} else {
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]
}
}