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
|
mut ident_var_info := left.info as ast.IdentVar
|
||||||
if ident_var_info.share == .shared_t {
|
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_flag(.shared_f)
|
||||||
|
left_type = left_type.set_nr_muls(1)
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
@ -2590,7 +2594,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
c.error('cannot assign to `$left`: ' +
|
c.error('cannot assign to `$left`: ' +
|
||||||
c.expected_msg(right_type_unwrapped, left_type_unwrapped), right.position())
|
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)
|
left_name := c.table.type_to_str(left_type_unwrapped)
|
||||||
mut rtype := right_type_unwrapped
|
mut rtype := right_type_unwrapped
|
||||||
if rtype.is_ptr() {
|
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
|
g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly
|
||||||
if is_amp {
|
if is_amp {
|
||||||
g.out.go_back(1) // delete the `&` already generated in `prefix_expr()
|
g.out.go_back(1) // delete the `&` already generated in `prefix_expr()
|
||||||
|
}
|
||||||
if g.is_shared {
|
if g.is_shared {
|
||||||
mut shared_typ := struct_init.typ.set_flag(.shared_f)
|
mut shared_typ := struct_init.typ.set_flag(.shared_f)
|
||||||
shared_styp = g.typ(shared_typ)
|
shared_styp = g.typ(shared_typ)
|
||||||
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.val = ($styp){')
|
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.val = ($styp){')
|
||||||
} else {
|
} else if is_amp {
|
||||||
g.write('($styp*)memdup(&($styp){')
|
g.write('($styp*)memdup(&($styp){')
|
||||||
}
|
|
||||||
} else if struct_init.typ.is_ptr() {
|
} else if struct_init.typ.is_ptr() {
|
||||||
basetyp := g.typ(struct_init.typ.set_nr_muls(0))
|
basetyp := g.typ(struct_init.typ.set_nr_muls(0))
|
||||||
if is_multiline {
|
if is_multiline {
|
||||||
|
@ -4708,10 +4708,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
g.write('&($basetyp){')
|
g.write('&($basetyp){')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if g.is_shared {
|
if is_multiline {
|
||||||
// TODO: non-ref shared should be forbidden
|
|
||||||
g.writeln('{.val = {')
|
|
||||||
} else if is_multiline {
|
|
||||||
g.writeln('($styp){')
|
g.writeln('($styp){')
|
||||||
} else {
|
} else {
|
||||||
g.write('($styp){')
|
g.write('($styp){')
|
||||||
|
@ -4870,10 +4867,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
}
|
}
|
||||||
g.write('}')
|
g.write('}')
|
||||||
if g.is_shared {
|
if g.is_shared {
|
||||||
g.write('}')
|
g.write('}, sizeof($shared_styp))')
|
||||||
if is_amp {
|
|
||||||
g.write(', sizeof($shared_styp))')
|
|
||||||
}
|
|
||||||
} else if is_amp {
|
} else if is_amp {
|
||||||
g.write(', sizeof($styp))')
|
g.write(', sizeof($styp))')
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,13 @@ fn f(shared x St, shared y St, shared z St) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_shared_lock() {
|
fn test_shared_lock() {
|
||||||
shared x := &St{
|
shared x := St{
|
||||||
a: 5
|
a: 5
|
||||||
}
|
}
|
||||||
shared y := &St{
|
shared y := &St{
|
||||||
a: 7
|
a: 7
|
||||||
}
|
}
|
||||||
shared z := &St{
|
shared z := St{
|
||||||
a: 1
|
a: 1
|
||||||
}
|
}
|
||||||
go f(shared x, shared y, shared z)
|
go f(shared x, shared y, shared z)
|
||||||
|
|
Loading…
Reference in New Issue