cgen: fix shared field init (#11061)
parent
44bacfc931
commit
91ade5bf8c
|
@ -2004,7 +2004,10 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
|
||||||
} else {
|
} else {
|
||||||
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.mtx = {0}, .val =')
|
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.expr(expr)
|
||||||
|
g.is_shared = old_is_shared
|
||||||
g.writeln('}, sizeof($shared_styp))')
|
g.writeln('}, sizeof($shared_styp))')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -5241,7 +5244,11 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
}
|
}
|
||||||
// User set fields
|
// User set fields
|
||||||
mut initialized := false
|
mut initialized := false
|
||||||
|
mut old_is_shared := g.is_shared
|
||||||
for i, field in struct_init.fields {
|
for i, field in struct_init.fields {
|
||||||
|
if !field.typ.has_flag(.shared_f) {
|
||||||
|
g.is_shared = false
|
||||||
|
}
|
||||||
inited_fields[field.name] = i
|
inited_fields[field.name] = i
|
||||||
if sym.kind != .struct_ {
|
if sym.kind != .struct_ {
|
||||||
field_name := if sym.language == .v { c_name(field.name) } else { field.name }
|
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
|
initialized = true
|
||||||
}
|
}
|
||||||
|
g.is_shared = old_is_shared
|
||||||
}
|
}
|
||||||
|
g.is_shared = old_is_shared
|
||||||
// The rest of the fields are zeroed.
|
// The rest of the fields are zeroed.
|
||||||
// `inited_fields` is a list of fields that have been init'ed, they are skipped
|
// `inited_fields` is a list of fields that have been init'ed, they are skipped
|
||||||
mut nr_fields := 1
|
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')
|
verror('union must not have more than 1 initializer')
|
||||||
}
|
}
|
||||||
if !info.is_union {
|
if !info.is_union {
|
||||||
|
old_is_shared2 := g.is_shared
|
||||||
mut used_embed_fields := []string{}
|
mut used_embed_fields := []string{}
|
||||||
init_field_names := info.fields.map(it.name)
|
init_field_names := info.fields.map(it.name)
|
||||||
// fields that are initialized but belong to the embedding
|
// 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
|
initialized = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g.is_shared = old_is_shared2
|
||||||
}
|
}
|
||||||
// g.zero_struct_fields(info, inited_fields)
|
// g.zero_struct_fields(info, inited_fields)
|
||||||
// nr_fields = info.fields.len
|
// nr_fields = info.fields.len
|
||||||
for mut field in info.fields {
|
for mut field in info.fields {
|
||||||
|
if !field.typ.has_flag(.shared_f) {
|
||||||
|
g.is_shared = false
|
||||||
|
}
|
||||||
if mut sym.info is ast.Struct {
|
if mut sym.info is ast.Struct {
|
||||||
mut found_equal_fields := 0
|
mut found_equal_fields := 0
|
||||||
for mut sifield in sym.info.fields {
|
for mut sifield in sym.info.fields {
|
||||||
|
@ -5391,7 +5405,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
g.write(',')
|
g.write(',')
|
||||||
}
|
}
|
||||||
initialized = true
|
initialized = true
|
||||||
|
g.is_shared = old_is_shared
|
||||||
}
|
}
|
||||||
|
g.is_shared = old_is_shared
|
||||||
}
|
}
|
||||||
if is_multiline {
|
if is_multiline {
|
||||||
g.indent--
|
g.indent--
|
||||||
|
|
|
@ -50,3 +50,28 @@ fn test_shared_lock() {
|
||||||
assert x.a == 7 && y.a == 5
|
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'
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue