From e3084ba6369054bafe1f5dbaae9b36867ec96f45 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 26 Sep 2024 01:29:06 -0300 Subject: [PATCH] cgen: fix variadic arg var passed to another call which expects variadic (fix #22315) (#22317) --- vlib/v/gen/c/fn.v | 21 ++++++++++++++------- vlib/v/tests/fns/variadic_sumtype_test.v | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 vlib/v/tests/fns/variadic_sumtype_test.v diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index e763c02a249dcc..67d44e9b456f65 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2607,16 +2607,23 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } } } else { - noscan := g.check_noscan(arr_info.elem_type) - g.write('new_array_from_c_array${noscan}(${variadic_count}, ${variadic_count}, sizeof(${elem_type}), _MOV((${elem_type}[${variadic_count}]){') - for j in arg_nr .. args.len { - g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language, + // passing variadic arg to another call which expects same array type + if args.len == 1 && args[arg_nr].typ.has_flag(.variadic) + && args[arg_nr].typ == varg_type { + g.ref_or_deref_arg(args[arg_nr], arr_info.elem_type, node.language, false) - if j < args.len - 1 { - g.write(', ') + } else { + noscan := g.check_noscan(arr_info.elem_type) + g.write('new_array_from_c_array${noscan}(${variadic_count}, ${variadic_count}, sizeof(${elem_type}), _MOV((${elem_type}[${variadic_count}]){') + for j in arg_nr .. args.len { + g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language, + false) + if j < args.len - 1 { + g.write(', ') + } } + g.write('}))') } - g.write('}))') } } else { g.write('__new_array(0, 0, sizeof(${elem_type}))') diff --git a/vlib/v/tests/fns/variadic_sumtype_test.v b/vlib/v/tests/fns/variadic_sumtype_test.v new file mode 100644 index 00000000000000..5d9c1332d03e02 --- /dev/null +++ b/vlib/v/tests/fns/variadic_sumtype_test.v @@ -0,0 +1,19 @@ +type Either = string | int + +fn tag(params ...Either) int { + mut c := 0 + for p in params { + if p is int { + c += p + } + } + return c +} + +fn div(params ...Either) int { + return tag(params) +} + +fn test_main() { + assert dump(div('foo', 1, 2)) == 3 +}