Skip to content

Commit

Permalink
cgen: fix array fixed empty struct code generated on clang (fix #21761)…
Browse files Browse the repository at this point in the history
… (#21764)
  • Loading branch information
felipensp authored Jul 1, 2024
1 parent 4fc6c7e commit 0682500
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
10 changes: 10 additions & 0 deletions vlib/v/ast/types.v
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,16 @@ pub fn (t &ArrayFixed) is_compatible(t2 ArrayFixed) bool {
return t.size == t2.size && t.elem_type == t2.elem_type
}

pub fn (t &TypeSymbol) is_empty_struct_array() bool {
if t.info is ArrayFixed {
elem_sym := global_table.final_sym(t.info.elem_type)
if elem_sym.info is Struct {
return elem_sym.info.fields.len == 0
}
}
return false
}

pub fn (t &TypeSymbol) is_array_fixed() bool {
if t.info is ArrayFixed {
return true
Expand Down
12 changes: 10 additions & 2 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -4295,7 +4295,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
fn (mut g Gen) enum_decl(node ast.EnumDecl) {
enum_name := util.no_dots(node.name)
is_flag := node.is_flag
if g.pref.ccompiler == 'msvc' {
if g.is_cc_msvc {
mut last_value := '0'
enum_typ_name := g.table.get_type_name(node.typ)
g.enum_typedefs.writeln('')
Expand Down Expand Up @@ -6278,6 +6278,8 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) {
default_initializer := g.type_default(field.typ)
if default_initializer == '{0}' && should_init {
def_builder.write_string(' = {0}')
} else if default_initializer == '{EMPTY_STRUCT_INITIALIZATION}' && should_init {
init = '\tmemcpy(${field.name}, (${styp}){${g.type_default(field.typ)}}, sizeof(${styp})); // global'
} else {
if field.name !in ['as_cast_type_indexes', 'g_memory_block', 'global_allocator'] {
init = '\t${field.name} = *(${styp}*)&((${styp}[]){${g.type_default(field.typ)}}[0]); // global'
Expand Down Expand Up @@ -7161,7 +7163,13 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
.string {
return '(string){.str=(byteptr)"", .is_lit=1}'
}
.interface_, .sum_type, .array_fixed, .multi_return, .thread {
.array_fixed {
if sym.is_empty_struct_array() {
return '{EMPTY_STRUCT_INITIALIZATION}'
}
return '{0}'
}
.interface_, .sum_type, .multi_return, .thread {
return '{0}'
}
.alias {
Expand Down
9 changes: 7 additions & 2 deletions vlib/v/gen/c/dumpexpr.v
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,16 @@ fn (mut g Gen) dump_expr_definitions() {
surrounder.builder_write_afters(mut dump_fns)
if is_fixed_arr_ret {
tmp_var := g.new_tmp_var()
init_str := if dump_sym.is_empty_struct_array() {
'{EMPTY_STRUCT_INITIALIZATION}'
} else {
'{0}'
}
if typ.is_ptr() {
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = HEAP(${g.typ(typ.set_nr_muls(0))}, {0});')
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = HEAP(${g.typ(typ.set_nr_muls(0))}, ${init_str});')
dump_fns.writeln('\tmemcpy(${tmp_var}->ret_arr, dump_arg, sizeof(${str_dumparg_type}));')
} else {
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = {0};')
dump_fns.writeln('\t${str_dumparg_ret_type} ${tmp_var} = ${init_str};')
dump_fns.writeln('\tmemcpy(${tmp_var}.ret_arr, dump_arg, sizeof(${str_dumparg_type}));')
}
dump_fns.writeln('\treturn ${tmp_var};')
Expand Down
16 changes: 16 additions & 0 deletions vlib/v/tests/array_fixed_empty_struct_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@[has_globals]
module main

const num_elements = 10

struct DummyStruct {
}

__global (
d [num_elements]DummyStruct
)

fn test_main() {
a := dump(d)
assert a.len == num_elements
}

0 comments on commit 0682500

Please sign in to comment.