From a98f6768905c59ea164b0cc805af5c5c924800fc Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 14 Apr 2026 12:45:32 +0300 Subject: [PATCH] cgen: (bug report summary) Builder Error (fixes #17430) --- vlib/v/gen/c/auto_eq_methods.v | 17 +++++++++++++++-- .../array_string_ref_compare_test.v | 17 +++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/builtin_arrays/array_string_ref_compare_test.v diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index 8cbcf3e81..1c5e8f050 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -13,6 +13,15 @@ fn (mut g Gen) equality_fn(typ ast.Type) string { return res } +@[inline] +fn string_eq_expr(left string, right string, is_ptr bool) string { + return if is_ptr { + '(${left} == ${right} || (${left} != 0 && ${right} != 0 && (((*${left}).len == (*${right}).len && (*${left}).len == 0) || builtin__fast_string_eq(*${left}, *${right}))))' + } else { + '(((${left}).len == (${right}).len && (${left}).len == 0) || builtin__fast_string_eq(${left}, ${right}))' + } +} + @[inline] fn (mut g Gen) eq_fn_key(typ ast.Type) ast.Type { return g.unwrap_generic(typ).set_nr_muls(0) @@ -392,7 +401,9 @@ fn (mut g Gen) gen_array_equality_fn(left_type ast.Type) string { fn_builder.writeln('\tfor (${ast.int_type_name} i = 0; i < ${left_len}; ++i) {') // compare every pair of elements of the two arrays if elem.sym.kind == .string { - fn_builder.writeln('\t\tif (!builtin__string__eq(*((${ptr_elem_styp}*)((byte*)${left_data}+(i*${left_elem}))), *((${ptr_elem_styp}*)((byte*)${right_data}+(i*${right_elem}))))) {') + left_arg := '*((${ptr_elem_styp}*)((byte*)${left_data}+(i*${left_elem})))' + right_arg := '*((${ptr_elem_styp}*)((byte*)${right_data}+(i*${right_elem})))' + fn_builder.writeln('\t\tif (!${string_eq_expr(left_arg, right_arg, elem.typ.is_ptr())}) {') } else if elem.sym.kind == .sum_type && !elem.typ.is_ptr() { eq_fn := g.gen_sumtype_equality_fn(elem.typ) fn_builder.writeln('\t\tif (!${eq_fn}_sumtype_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {') @@ -481,7 +492,9 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left_type ast.Type) string { fn_builder.writeln('\tfor (${ast.int_type_name} i = 0; i < ${size}; ++i) {') // compare every pair of elements of the two fixed arrays if elem.sym.kind == .string { - fn_builder.writeln('\t\tif (!builtin__string__eq(((string*)${left})[i], ((string*)${right})[i])) {') + left_arg := '${left}[i]' + right_arg := '${right}[i]' + fn_builder.writeln('\t\tif (!${string_eq_expr(left_arg, right_arg, elem.typ.is_ptr())}) {') } else if elem.sym.kind == .sum_type && !elem.typ.is_ptr() { eq_fn := g.gen_sumtype_equality_fn(elem.typ) fn_builder.writeln('\t\tif (!${eq_fn}_sumtype_eq(${left}[i], ${right}[i])) {') diff --git a/vlib/v/tests/builtin_arrays/array_string_ref_compare_test.v b/vlib/v/tests/builtin_arrays/array_string_ref_compare_test.v new file mode 100644 index 000000000..615a93baa --- /dev/null +++ b/vlib/v/tests/builtin_arrays/array_string_ref_compare_test.v @@ -0,0 +1,17 @@ +fn test_nested_array_of_string_references_compare_empty_in_mut_loop() { + v1 := 'abc' + v2 := 'def' + mut sec_array := [][]&string{len: 1, init: []&string{}} + sec_array[0] << &v1 + sec_array[0] << &v2 + mut found_non_empty := false + for mut elem in sec_array { + if elem != [] { + found_non_empty = true + assert elem.len == 2 + assert *elem[0] == 'abc' + assert *elem[1] == 'def' + } + } + assert found_non_empty +} -- 2.39.5