checker/cgen: auto initialize `shared` elements of structs (#9669)

pull/9677/head^2
Uwe Krüger 2021-04-11 09:30:23 +02:00 committed by GitHub
parent 3241611871
commit 954c436d28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 6 deletions

View File

@ -646,7 +646,8 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
if field.has_default_expr || field.name in inited_fields {
continue
}
if field.typ.is_ptr() && !struct_init.has_update_expr && !c.pref.translated {
if field.typ.is_ptr() && !field.typ.has_flag(.shared_f)
&& !struct_init.has_update_expr && !c.pref.translated {
c.error('reference field `${type_sym.name}.$field.name` must be initialized',
struct_init.pos)
}

View File

@ -5743,23 +5743,36 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
return '{0}'
}
// Always set pointers to 0
if typ.is_ptr() {
if typ.is_ptr() && !typ.has_flag(.shared_f) {
return '0'
}
sym := g.table.get_type_symbol(typ)
if sym.kind == .array {
elem_sym := g.typ(sym.array_info().elem_type)
elem_typ := sym.array_info().elem_type
elem_sym := g.typ(elem_typ)
mut elem_type_str := util.no_dots(elem_sym)
if elem_type_str.starts_with('C__') {
elem_type_str = elem_type_str[3..]
}
return '__new_array(0, 1, sizeof($elem_type_str))'
init_str := '__new_array(0, 1, sizeof($elem_type_str))'
if typ.has_flag(.shared_f) {
atyp := '__shared__Array_${g.table.get_type_symbol(elem_typ).cname}'
return '($atyp*)__dup_shared_array(&($atyp){.val = $init_str}, sizeof($atyp))'
} else {
return init_str
}
}
if sym.kind == .map {
info := sym.map_info()
key_typ := g.table.get_type_symbol(info.key_type)
hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ)
return 'new_map(sizeof(${g.typ(info.key_type)}), sizeof(${g.typ(info.value_type)}), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)'
init_str := 'new_map(sizeof(${g.typ(info.key_type)}), sizeof(${g.typ(info.value_type)}), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)'
if typ.has_flag(.shared_f) {
mtyp := '__shared__Map_${key_typ.cname}_${g.table.get_type_symbol(info.value_type).cname}'
return '($mtyp*)__dup_shared_map(&($mtyp){.val = $init_str}, sizeof($mtyp))'
} else {
return init_str
}
}
// User struct defined in another module.
// if typ.contains('__') {
@ -5786,7 +5799,12 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
} else {
init_str += '0}'
}
return init_str
if typ.has_flag(.shared_f) {
styp := '__shared__${g.table.get_type_symbol(typ).cname}'
return '($styp*)__dup${styp}(&($styp){.val = $init_str}, sizeof($styp))'
} else {
return init_str
}
}
// if typ.ends_with('Fn') { // TODO
// return '0'

View File

@ -8,6 +8,18 @@ struct Abc {
i int
}
fn test_shared_struct_auto_struct() {
e := Abc{}
shared a := e.a
lock a {
a.n = 17
}
r := rlock a {
a.n
}
assert r == 17
}
fn test_shared_struct_in_struct() {
shared y := Xyz{
n: 7
@ -50,6 +62,20 @@ struct Efg {
i int
}
fn test_shared_auto_init_array() {
e := Efg{}
shared a := e.a
lock a {
a << 23.0625
a << -133.25
a << 0.125
}
r := rlock a {
a[1]
}
assert r == -133.25
}
fn test_shared_array_in_struct() {
x := Efg{
a: [1.25, 2.75, 7, 13.0625]
@ -76,6 +102,18 @@ struct Hjk {
i int
}
fn test_shared_auto_init_map() {
a := Hjk{}
shared m := a.m
lock m {
m['xcv'] = -31.125
}
r := rlock m {
m['xcv']
}
assert r == -31.125
}
fn test_shared_map_in_struct() {
x := Hjk{
m: map{