From 75d1b54f7bd5c14cfa7fd240ce8583ab61ed2c27 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 18 Apr 2021 21:34:25 +0800 Subject: [PATCH] cgen: fix empty struct init using macro (#9787) --- vlib/v/gen/c/cgen.v | 27 ++++++++++++++----- vlib/v/gen/c/cheaders.v | 6 ++--- .../generics_with_nested_generics_fn_test.v | 2 -- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index c5dcd109f9..90b310b39e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5122,9 +5122,10 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { } // 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 := 0 + mut nr_fields := 1 if sym.kind == .struct_ { info := sym.info as ast.Struct + nr_fields = info.fields.len if info.is_union && struct_init.fields.len > 1 { verror('union must not have more than 1 initializer') } @@ -5205,7 +5206,10 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { } g.write(field.name) } else { - g.zero_struct_field(field) + if !g.zero_struct_field(field) { + nr_fields-- + continue + } } if is_multiline { g.writeln(',') @@ -5220,7 +5224,11 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { } if !initialized { - g.write('0') + if nr_fields > 0 { + g.write('0') + } else { + g.write('EMPTY_STRUCT_INITIALIZATION') + } } g.write('}') @@ -5231,19 +5239,26 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { } } -fn (mut g Gen) zero_struct_field(field ast.StructField) { +fn (mut g Gen) zero_struct_field(field ast.StructField) bool { + sym := g.table.get_type_symbol(field.typ) + if sym.kind == .struct_ { + info := sym.info as ast.Struct + if info.fields.len == 0 { + return false + } + } field_name := c_name(field.name) g.write('.$field_name = ') - sym := g.table.get_type_symbol(field.typ) if field.has_default_expr { if sym.kind in [.sum_type, .interface_] { g.expr_with_cast(field.default_expr, field.default_expr_typ, field.typ) - return + return true } g.expr(field.default_expr) } else { g.write(g.type_default(field.typ)) } + return true } // fn (mut g Gen) zero_struct_fields(info ast.Struct, inited_fields map[string]int) { diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index 3518e44762..63290ec06b 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -179,7 +179,7 @@ string _STR_TMP(const char *fmt, ...) { c_common_macros = ' #define EMPTY_VARG_INITIALIZATION 0 #define EMPTY_STRUCT_DECLARATION -#define EMPTY_STRUCT_INITIALIZATION 0 +#define EMPTY_STRUCT_INITIALIZATION // Due to a tcc bug, the length of an array needs to be specified, but GCC crashes if it is... #define EMPTY_ARRAY_OF_ELEMS(x,n) (x[]) #define TCCSKIP(x) x @@ -209,13 +209,13 @@ string _STR_TMP(const char *fmt, ...) { #endif #ifdef _MSC_VER #undef __V_GCC__ + #undef EMPTY_STRUCT_INITIALIZATION + #define EMPTY_STRUCT_INITIALIZATION 0 #endif #ifdef __TINYC__ #undef EMPTY_STRUCT_DECLARATION - #undef EMPTY_STRUCT_INITIALIZATION #define EMPTY_STRUCT_DECLARATION char _dummy - #define EMPTY_STRUCT_INITIALIZATION 0 #undef EMPTY_ARRAY_OF_ELEMS #define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n]) #undef __NOINLINE diff --git a/vlib/v/tests/generics_with_nested_generics_fn_test.v b/vlib/v/tests/generics_with_nested_generics_fn_test.v index 6574ffe02e..879788fe8d 100644 --- a/vlib/v/tests/generics_with_nested_generics_fn_test.v +++ b/vlib/v/tests/generics_with_nested_generics_fn_test.v @@ -1,9 +1,7 @@ struct NestedGeneric { - a int } struct Context { - b int } struct App {