From d5ce91a5eb9751528b54c0bae6690041d30d5f21 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 25 Mar 2026 16:42:26 +0300 Subject: [PATCH] cgen: fix static array unknown type c issue (fixes #24164) --- vlib/v/gen/c/cgen.v | 44 ++++++++++++++----- ..._array_enum_fn_type_dependency.c.must_have | 1 + .../fixed_array_enum_fn_type_dependency.vv | 9 ++++ .../fixed_array_enum_submodule_test.c.v | 10 +++++ .../c_function/some_module/some_module.v | 5 +++ 5 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.c.must_have create mode 100644 vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.vv create mode 100644 vlib/v/tests/c_function/fixed_array_enum_submodule_test.c.v create mode 100644 vlib/v/tests/c_function/some_module/some_module.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 8522d0f80..17f5f0c6d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2403,13 +2403,7 @@ pub fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol) { g.styp(func.return_type) g.type_definitions.write_string('typedef ${ret_typ} (${msvc_call_conv}*${fn_name})(') for i, param in func.params { - const_prefix := if param.typ.is_any_kind_of_pointer() && !param.is_mut - && param.name.starts_with('const_') { - 'const ' - } else { - '' - } - g.type_definitions.write_string('${const_prefix}${g.styp(param.typ)}') + g.type_definitions.write_string(g.fn_param_type_decl(param.typ, '')) if i < func.params.len - 1 { g.type_definitions.write_string(',') } @@ -2418,6 +2412,38 @@ pub fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol) { } } +// fn_param_type_decl emits fixed-array parameters as direct C array declarators so +// function type definitions do not depend on later fixed-array typedef ordering. +fn (mut g Gen) fn_param_type_decl(typ ast.Type, name string) string { + styp := g.styp(typ) + if typ.is_ptr() || typ.has_flag(.option) || typ.has_flag(.result) { + return if name == '' { styp } else { '${styp} ${name}' } + } + mut current_typ := g.table.unaliased_type(typ) + mut current_sym := g.table.sym(current_typ) + if current_sym.kind != .array_fixed { + return if name == '' { styp } else { '${styp} ${name}' } + } + mut dims := []string{} + for current_sym.kind == .array_fixed { + info := current_sym.info as ast.ArrayFixed + dims << '[${info.size}]' + if info.elem_type.is_ptr() || info.elem_type.has_flag(.option) + || info.elem_type.has_flag(.result) { + base_styp := g.styp(info.elem_type) + decl := if name == '' { dims.join('') } else { '${name}${dims.join('')}' } + return '${base_styp} ${decl}' + } + current_typ = g.table.unaliased_type(info.elem_type) + current_sym = g.table.sym(current_typ) + } + if current_sym.info is ast.FnType { + return if name == '' { styp } else { '${styp} ${name}' } + } + decl := if name == '' { dims.join('') } else { '${name}${dims.join('')}' } + return '${g.styp(current_typ)} ${decl}' +} + pub fn (mut g Gen) write_array_fixed_return_types() { fixed_arr_wrappers := g.table.type_symbols.filter(it.info is ast.ArrayFixed && !it.info.elem_type.has_flag(.generic)) @@ -4425,9 +4451,7 @@ fn (mut g Gen) write_fn_ptr_decl(func &ast.FnType, ptr_name string) { g.write('${ret_styp} (*${ptr_name}) (') arg_len := func.func.params.len for i, arg in func.func.params { - arg_styp := g.styp(arg.typ) - g.write(arg_styp) - g.write(' ${arg.name}') + g.write(g.fn_param_type_decl(arg.typ, arg.name)) if i < arg_len - 1 { g.write(', ') } diff --git a/vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.c.must_have b/vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.c.must_have new file mode 100644 index 000000000..f8a87ca14 --- /dev/null +++ b/vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.c.must_have @@ -0,0 +1 @@ +typedef void (*fixedarr__Callback)(voidptr,fixedarr__FlagBits [2]); diff --git a/vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.vv b/vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.vv new file mode 100644 index 000000000..b024a2bba --- /dev/null +++ b/vlib/v/gen/c/testdata/fixed_array_enum_fn_type_dependency.vv @@ -0,0 +1,9 @@ +// vtest vflags: -shared +module fixedarr + +enum FlagBits { + dsntmatter +} + +@[markused] +pub type Callback = fn (voidptr, [2]FlagBits) diff --git a/vlib/v/tests/c_function/fixed_array_enum_submodule_test.c.v b/vlib/v/tests/c_function/fixed_array_enum_submodule_test.c.v new file mode 100644 index 000000000..7a3c0116f --- /dev/null +++ b/vlib/v/tests/c_function/fixed_array_enum_submodule_test.c.v @@ -0,0 +1,10 @@ +module main + +import some_module as sm + +@[markused] +type PFN_set_enum_array_submodule = fn (voidptr, [2]sm.Flag_bits2) + +fn test_fn_type_with_submodule_enum_fixed_array_second_param() { + assert true +} diff --git a/vlib/v/tests/c_function/some_module/some_module.v b/vlib/v/tests/c_function/some_module/some_module.v new file mode 100644 index 000000000..5d8688dd3 --- /dev/null +++ b/vlib/v/tests/c_function/some_module/some_module.v @@ -0,0 +1,5 @@ +module some_module + +pub enum Flag_bits2 { + dsntmatter2 +} -- 2.39.5