checker/cgen: put `shared` struct always on heap (#8492)

pull/8496/head
Uwe Krüger 2021-02-01 14:39:36 +01:00 committed by GitHub
parent 5b9a7bf6b3
commit 44ec9e3ebc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 18 deletions

View File

@ -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() {

View File

@ -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))')
} }

View File

@ -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)