From 3ee858cd79aec2fac5d18cad9be9d7a60195d308 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 19 Apr 2020 05:44:39 +0300 Subject: [PATCH] cgen: fix struct initialization bugs --- vlib/v/gen/cgen.v | 15 +++++++------- vlib/v/tests/struct_test.v | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 52cb010f67..82ec688697 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -249,12 +249,12 @@ pub fn (var g Gen) write_typedef_types() { info := typ.info as table.FnType func := info.func if !info.has_decl { - fn_name := if func.is_c { - func.name.replace('.', '__') + fn_name := if func.is_c { + func.name.replace('.', '__') } else if info.is_anon { typ.name - } else { - c_name(func.name) + } else { + c_name(func.name) } g.definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(') for i, arg in func.args { @@ -1980,13 +1980,14 @@ fn (var g Gen) struct_init(struct_init ast.StructInit) { continue } field_name := c_name(field.name) + g.write('\t.$field_name = ') if field.has_default_expr { g.expr(field.default_expr) - g.writeln(',') + } else { - zero := g.type_default(field.typ) - g.writeln('\t.$field_name = $zero,') + g.write(g.type_default(field.typ)) } + g.writeln(',') } } if struct_init.fields.len == 0 && info.fields.len == 0 { diff --git a/vlib/v/tests/struct_test.v b/vlib/v/tests/struct_test.v index 8cbdcbfb61..b72db070f0 100644 --- a/vlib/v/tests/struct_test.v +++ b/vlib/v/tests/struct_test.v @@ -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 +}