checker/cgen: put `shared` struct always on heap (#8492)
parent
5b9a7bf6b3
commit
44ec9e3ebc
|
@ -2511,7 +2511,11 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
}
|
||||
mut ident_var_info := left.info as ast.IdentVar
|
||||
if ident_var_info.share == .shared_t {
|
||||
if left_type.nr_muls() > 1 {
|
||||
c.error('shared cannot be multi level reference', left.pos)
|
||||
}
|
||||
left_type = left_type.set_flag(.shared_f)
|
||||
left_type = left_type.set_nr_muls(1)
|
||||
}
|
||||
if ident_var_info.share == .atomic_t {
|
||||
left_type = left_type.set_flag(.atomic_f)
|
||||
|
@ -2590,7 +2594,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
c.error('cannot assign to `$left`: ' +
|
||||
c.expected_msg(right_type_unwrapped, left_type_unwrapped), right.position())
|
||||
}
|
||||
if (right is ast.StructInit || !right_is_ptr) && !right_sym.is_number() {
|
||||
if (right is ast.StructInit || !right_is_ptr) && !(right_sym.is_number()
|
||||
|| left_type.has_flag(.shared_f)) {
|
||||
left_name := c.table.type_to_str(left_type_unwrapped)
|
||||
mut rtype := right_type_unwrapped
|
||||
if rtype.is_ptr() {
|
||||
|
|
|
@ -4693,13 +4693,13 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly
|
||||
if is_amp {
|
||||
g.out.go_back(1) // delete the `&` already generated in `prefix_expr()
|
||||
if g.is_shared {
|
||||
mut shared_typ := struct_init.typ.set_flag(.shared_f)
|
||||
shared_styp = g.typ(shared_typ)
|
||||
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.val = ($styp){')
|
||||
} else {
|
||||
g.write('($styp*)memdup(&($styp){')
|
||||
}
|
||||
}
|
||||
if g.is_shared {
|
||||
mut shared_typ := struct_init.typ.set_flag(.shared_f)
|
||||
shared_styp = g.typ(shared_typ)
|
||||
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.val = ($styp){')
|
||||
} else if is_amp {
|
||||
g.write('($styp*)memdup(&($styp){')
|
||||
} else if struct_init.typ.is_ptr() {
|
||||
basetyp := g.typ(struct_init.typ.set_nr_muls(0))
|
||||
if is_multiline {
|
||||
|
@ -4708,10 +4708,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
g.write('&($basetyp){')
|
||||
}
|
||||
} else {
|
||||
if g.is_shared {
|
||||
// TODO: non-ref shared should be forbidden
|
||||
g.writeln('{.val = {')
|
||||
} else if is_multiline {
|
||||
if is_multiline {
|
||||
g.writeln('($styp){')
|
||||
} else {
|
||||
g.write('($styp){')
|
||||
|
@ -4870,10 +4867,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
}
|
||||
g.write('}')
|
||||
if g.is_shared {
|
||||
g.write('}')
|
||||
if is_amp {
|
||||
g.write(', sizeof($shared_styp))')
|
||||
}
|
||||
g.write('}, sizeof($shared_styp))')
|
||||
} else if is_amp {
|
||||
g.write(', sizeof($styp))')
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@ fn f(shared x St, shared y St, shared z St) {
|
|||
}
|
||||
|
||||
fn test_shared_lock() {
|
||||
shared x := &St{
|
||||
shared x := St{
|
||||
a: 5
|
||||
}
|
||||
shared y := &St{
|
||||
a: 7
|
||||
}
|
||||
shared z := &St{
|
||||
shared z := St{
|
||||
a: 1
|
||||
}
|
||||
go f(shared x, shared y, shared z)
|
||||
|
|
Loading…
Reference in New Issue