Skip to content

Commit 0682500

Browse files
authored
cgen: fix array fixed empty struct code generated on clang (fix #21761) (#21764)
1 parent 4fc6c7e commit 0682500

File tree

4 files changed

+43
-4
lines changed

4 files changed

+43
-4
lines changed

vlib/v/ast/types.v

+10
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,16 @@ pub fn (t &ArrayFixed) is_compatible(t2 ArrayFixed) bool {
925925
return t.size == t2.size && t.elem_type == t2.elem_type
926926
}
927927

928+
pub fn (t &TypeSymbol) is_empty_struct_array() bool {
929+
if t.info is ArrayFixed {
930+
elem_sym := global_table.final_sym(t.info.elem_type)
931+
if elem_sym.info is Struct {
932+
return elem_sym.info.fields.len == 0
933+
}
934+
}
935+
return false
936+
}
937+
928938
pub fn (t &TypeSymbol) is_array_fixed() bool {
929939
if t.info is ArrayFixed {
930940
return true

vlib/v/gen/c/cgen.v

+10-2
Original file line numberDiff line numberDiff line change
@@ -4295,7 +4295,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
42954295
fn (mut g Gen) enum_decl(node ast.EnumDecl) {
42964296
enum_name := util.no_dots(node.name)
42974297
is_flag := node.is_flag
4298-
if g.pref.ccompiler == 'msvc' {
4298+
if g.is_cc_msvc {
42994299
mut last_value := '0'
43004300
enum_typ_name := g.table.get_type_name(node.typ)
43014301
g.enum_typedefs.writeln('')
@@ -6278,6 +6278,8 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) {
62786278
default_initializer := g.type_default(field.typ)
62796279
if default_initializer == '{0}' && should_init {
62806280
def_builder.write_string(' = {0}')
6281+
} else if default_initializer == '{EMPTY_STRUCT_INITIALIZATION}' && should_init {
6282+
init = '\tmemcpy(${field.name}, (${styp}){${g.type_default(field.typ)}}, sizeof(${styp})); // global'
62816283
} else {
62826284
if field.name !in ['as_cast_type_indexes', 'g_memory_block', 'global_allocator'] {
62836285
init = '\t${field.name} = *(${styp}*)&((${styp}[]){${g.type_default(field.typ)}}[0]); // global'
@@ -7161,7 +7163,13 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
71617163
.string {
71627164
return '(string){.str=(byteptr)"", .is_lit=1}'
71637165
}
7164-
.interface_, .sum_type, .array_fixed, .multi_return, .thread {
7166+
.array_fixed {
7167+
if sym.is_empty_struct_array() {
7168+
return '{EMPTY_STRUCT_INITIALIZATION}'
7169+
}
7170+
return '{0}'
7171+
}
7172+
.interface_, .sum_type, .multi_return, .thread {
71657173
return '{0}'
71667174
}
71677175
.alias {

vlib/v/gen/c/dumpexpr.v

+7-2
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,16 @@ fn (mut g Gen) dump_expr_definitions() {
227227
surrounder.builder_write_afters(mut dump_fns)
228228
if is_fixed_arr_ret {
229229
tmp_var := g.new_tmp_var()
230+
init_str := if dump_sym.is_empty_struct_array() {
231+
'{EMPTY_STRUCT_INITIALIZATION}'
232+
} else {
233+
'{0}'
234+
}
230235
if typ.is_ptr() {
231-
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = HEAP(${g.typ(typ.set_nr_muls(0))}, {0});')
236+
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = HEAP(${g.typ(typ.set_nr_muls(0))}, ${init_str});')
232237
dump_fns.writeln('\tmemcpy(${tmp_var}->ret_arr, dump_arg, sizeof(${str_dumparg_type}));')
233238
} else {
234-
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = {0};')
239+
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = ${init_str};')
235240
dump_fns.writeln('\tmemcpy(${tmp_var}.ret_arr, dump_arg, sizeof(${str_dumparg_type}));')
236241
}
237242
dump_fns.writeln('\treturn ${tmp_var};')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@[has_globals]
2+
module main
3+
4+
const num_elements = 10
5+
6+
struct DummyStruct {
7+
}
8+
9+
__global (
10+
d [num_elements]DummyStruct
11+
)
12+
13+
fn test_main() {
14+
a := dump(d)
15+
assert a.len == num_elements
16+
}

0 commit comments

Comments
 (0)