cgen: fix shared field init (#11061)

pull/11079/head
Daniel Däschle 2021-08-06 04:11:03 +02:00 committed by GitHub
parent 44bacfc931
commit 91ade5bf8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 0 deletions

View File

@ -2004,7 +2004,10 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
} else {
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.mtx = {0}, .val =')
}
old_is_shared := g.is_shared
g.is_shared = false
g.expr(expr)
g.is_shared = old_is_shared
g.writeln('}, sizeof($shared_styp))')
return
}
@ -5241,7 +5244,11 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
}
// User set fields
mut initialized := false
mut old_is_shared := g.is_shared
for i, field in struct_init.fields {
if !field.typ.has_flag(.shared_f) {
g.is_shared = false
}
inited_fields[field.name] = i
if sym.kind != .struct_ {
field_name := if sym.language == .v { c_name(field.name) } else { field.name }
@ -5273,7 +5280,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
}
initialized = true
}
g.is_shared = old_is_shared
}
g.is_shared = old_is_shared
// The rest of the fields are zeroed.
// `inited_fields` is a list of fields that have been init'ed, they are skipped
mut nr_fields := 1
@ -5284,6 +5293,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
verror('union must not have more than 1 initializer')
}
if !info.is_union {
old_is_shared2 := g.is_shared
mut used_embed_fields := []string{}
init_field_names := info.fields.map(it.name)
// fields that are initialized but belong to the embedding
@ -5311,10 +5321,14 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
initialized = true
}
}
g.is_shared = old_is_shared2
}
// g.zero_struct_fields(info, inited_fields)
// nr_fields = info.fields.len
for mut field in info.fields {
if !field.typ.has_flag(.shared_f) {
g.is_shared = false
}
if mut sym.info is ast.Struct {
mut found_equal_fields := 0
for mut sifield in sym.info.fields {
@ -5391,7 +5405,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
g.write(',')
}
initialized = true
g.is_shared = old_is_shared
}
g.is_shared = old_is_shared
}
if is_multiline {
g.indent--

View File

@ -50,3 +50,28 @@ fn test_shared_lock() {
assert x.a == 7 && y.a == 5
}
}
struct App {
id string = 'test'
mut:
app_data shared AppData
}
fn (mut a App) init_server_direct() {
lock a.app_data {
a.app_data = AppData{}
}
}
struct AppData {
id string = 'foo'
}
fn test_shared_field_init() {
mut app1 := App{}
app1.init_server_direct()
id := rlock app1.app_data {
app1.app_data.id
}
assert id == 'foo'
}