diff --git a/vlib/arrays/arrays_test.v b/vlib/arrays/arrays_test.v index 176d7c0088..ee05cfac1f 100644 --- a/vlib/arrays/arrays_test.v +++ b/vlib/arrays/arrays_test.v @@ -307,4 +307,8 @@ fn test_array_append_empty_struct() { mut names := []XYZ{cap: 2} names << XYZ{} assert (XYZ{} in names) == true + + // test fixed array + array := [XYZ{}] + assert (XYZ{} in names) == true } diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index ef32a7e9c4..2941a21943 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -151,7 +151,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } else { g.write('0, ') } - if elem_type.unaliased_sym.kind == .function { + if elem_type.unaliased_sym.kind == .function || g.is_empty_struct(elem_type) { g.write('sizeof(voidptr), ') } else { g.write('sizeof($elem_styp), ') @@ -217,7 +217,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } else { g.write('0, ') } - if elem_type.unaliased_sym.kind == .function { + if elem_type.unaliased_sym.kind == .function || g.is_empty_struct(elem_type) { g.write('sizeof(voidptr), ') } else { g.write('sizeof($elem_styp), ') @@ -251,6 +251,8 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { len := node.exprs.len if elem_type.unaliased_sym.kind == .function { g.write('new_array_from_c_array($len, $len, sizeof(voidptr), _MOV((voidptr[$len]){') + } else if g.is_empty_struct(elem_type) { + g.write('new_array_from_c_array${noscan}($len, $len, sizeof(voidptr), _MOV(($elem_styp[$len]){') } else { g.write('new_array_from_c_array${noscan}($len, $len, sizeof($elem_styp), _MOV(($elem_styp[$len]){') } diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index 16ed50e537..f179ce908f 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -258,7 +258,7 @@ static void __closure_destroy(void *closure) { const c_common_macros = ' #define EMPTY_VARG_INITIALIZATION 0 -#define EMPTY_STRUCT_DECLARATION char _dummy +#define EMPTY_STRUCT_DECLARATION #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[]) @@ -300,6 +300,8 @@ const c_common_macros = ' #endif #ifdef __TINYC__ + #undef EMPTY_STRUCT_DECLARATION + #define EMPTY_STRUCT_DECLARATION char _dummy #undef EMPTY_ARRAY_OF_ELEMS #define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n]) #undef __NOINLINE @@ -574,8 +576,10 @@ voidptr memdup(voidptr src, int sz); #define _Atomic volatile // MSVC cannot parse some things properly + #undef EMPTY_STRUCT_DECLARATION #undef OPTION_CAST + #define EMPTY_STRUCT_DECLARATION char __pad #define OPTION_CAST(x) #undef __NOINLINE #undef __IRQHANDLER diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index fa3600c33d..29fb490bbd 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -305,3 +305,18 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool { } return true } + +fn (mut g Gen) is_empty_struct(t Type) bool { + sym := t.unaliased_sym + match sym.info { + ast.Struct { + if sym.info.fields.len > 0 || sym.info.embeds.len > 0 { + return false + } + return true + } + else { + return false + } + } +}