cgen: fix struct initialization bugs

pull/4509/head
Alexey 2020-04-19 05:44:39 +03:00 committed by GitHub
parent be0a8794c2
commit 3ee858cd79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 7 deletions

View File

@ -249,12 +249,12 @@ pub fn (var g Gen) write_typedef_types() {
info := typ.info as table.FnType info := typ.info as table.FnType
func := info.func func := info.func
if !info.has_decl { if !info.has_decl {
fn_name := if func.is_c { fn_name := if func.is_c {
func.name.replace('.', '__') func.name.replace('.', '__')
} else if info.is_anon { } else if info.is_anon {
typ.name typ.name
} else { } else {
c_name(func.name) c_name(func.name)
} }
g.definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(') g.definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(')
for i, arg in func.args { for i, arg in func.args {
@ -1980,13 +1980,14 @@ fn (var g Gen) struct_init(struct_init ast.StructInit) {
continue continue
} }
field_name := c_name(field.name) field_name := c_name(field.name)
g.write('\t.$field_name = ')
if field.has_default_expr { if field.has_default_expr {
g.expr(field.default_expr) g.expr(field.default_expr)
g.writeln(',')
} else { } else {
zero := g.type_default(field.typ) g.write(g.type_default(field.typ))
g.writeln('\t.$field_name = $zero,')
} }
g.writeln(',')
} }
} }
if struct_init.fields.len == 0 && info.fields.len == 0 { if struct_init.fields.len == 0 && info.fields.len == 0 {

View File

@ -265,3 +265,44 @@ fn test_levels() {
} }
} }
} }
// Struct where an inizialized field is after a non-initilized field.
struct StructWithDefaultValues1 {
field_required int
field_optional int = 5
}
// Struct where an inizialized field is before a non-initilized field.
struct StructWithDefaultValues2 {
field_optional int = 3
field_required int
}
// Struct where an inizialized field is before several non-initilized fields.
struct StructWithDefaultValues3 {
field_optional int = 2
field_required int
field_required_too int
}
fn test_struct_with_default_values_init() {
s1 := StructWithDefaultValues1{ field_required: 5 }
s2 := StructWithDefaultValues2{ field_required: 5 }
// Partially initialized
s3 := StructWithDefaultValues3{ field_required: 5 }
assert s1.field_optional == 5
assert s2.field_optional == 3
assert s3.field_optional == 2
}
fn test_struct_with_default_values_no_init() {
// Don't inititialize
s1 := StructWithDefaultValues1{}
s2 := StructWithDefaultValues2{}
s3 := StructWithDefaultValues3{}
assert s1.field_optional == 5
assert s2.field_optional == 3
assert s3.field_optional == 2
}