Skip to content

Commit ca1e23a

Browse files
authored
cgen: fix auto eq for fixed array (fix #23149) (#23169)
1 parent 90cef28 commit ca1e23a

File tree

6 files changed

+66
-6
lines changed

6 files changed

+66
-6
lines changed

vlib/v/ast/types.v

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,16 @@ pub fn (t &Struct) is_unresolved_generic() bool {
10061006
return t.generic_types.len > 0 && t.concrete_types.len == 0
10071007
}
10081008

1009+
pub fn (t &TypeSymbol) is_primitive_fixed_array() bool {
1010+
if t.info is ArrayFixed {
1011+
return global_table.final_sym(t.info.elem_type).is_primitive()
1012+
} else if t.info is Alias {
1013+
return global_table.final_sym(t.info.parent_type).is_primitive_fixed_array()
1014+
} else {
1015+
return false
1016+
}
1017+
}
1018+
10091019
pub fn (t &TypeSymbol) is_array_fixed() bool {
10101020
if t.info is ArrayFixed {
10111021
return true

vlib/v/gen/c/auto_eq_methods.v

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,21 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left_type ast.Type) string {
437437

438438
mut fn_builder := strings.new_builder(512)
439439
fn_builder.writeln('inline bool ${ptr_styp}_arr_eq(${arg_styp} a, ${arg_styp} b) {')
440+
if left_type.has_flag(.option) {
441+
fn_builder.writeln('\tif (a.state != b.state) return false;')
442+
fn_builder.writeln('\tif (a.state == 2 && a.state == b.state) return true;')
443+
}
444+
if left_typ.sym.is_primitive_fixed_array() {
445+
suffix := if left_type.has_flag(.option) { '.data' } else { '[0]' }
446+
size_styp := if left_type.has_flag(.option) {
447+
g.base_type(left_typ.typ.set_nr_muls(0))
448+
} else {
449+
arg_styp
450+
}
451+
fn_builder.writeln('\tif (!memcmp(&a${suffix}, &b${suffix}, sizeof(${size_styp}))) {')
452+
fn_builder.writeln('\t\treturn true;')
453+
fn_builder.writeln('\t}')
454+
}
440455
fn_builder.writeln('\tfor (int i = 0; i < ${size}; ++i) {')
441456
// compare every pair of elements of the two fixed arrays
442457
if elem.sym.kind == .string {

vlib/v/gen/c/infix.v

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,17 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
216216
if left.typ.is_ptr() {
217217
g.write('*'.repeat(left.typ.nr_muls()))
218218
}
219+
if node.left is ast.StructInit && left.unaliased_sym.is_primitive_fixed_array() {
220+
s := g.styp(left.unaliased)
221+
g.write('(${s})')
222+
}
219223
g.expr(node.left)
220224
g.write(', ')
225+
if node.right is ast.StructInit
226+
&& right.unaliased_sym.is_primitive_fixed_array() {
227+
s := g.styp(right.unaliased)
228+
g.write('(${s})')
229+
}
221230
if right.typ.is_ptr() {
222231
g.write('*'.repeat(right.typ.nr_muls()))
223232
}
@@ -266,6 +275,10 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
266275
s := g.styp(left.unaliased)
267276
g.write('(${s})')
268277
}
278+
} else if node.left is ast.StructInit
279+
&& left.unaliased_sym.is_primitive_fixed_array() {
280+
s := g.styp(left.unaliased)
281+
g.write('(${s})')
269282
}
270283
g.expr(node.left)
271284
g.write(', ')
@@ -274,6 +287,10 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
274287
s := g.styp(right.unaliased)
275288
g.write('(${s})')
276289
}
290+
} else if node.right is ast.StructInit
291+
&& right.unaliased_sym.is_primitive_fixed_array() {
292+
s := g.styp(right.unaliased)
293+
g.write('(${s})')
277294
}
278295
g.expr(node.right)
279296
g.write(')')

vlib/v/gen/c/json.v

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -835,11 +835,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
835835
dec)
836836
}
837837
if field.typ.has_flag(.option) {
838-
if field_sym.kind == .array_fixed {
839-
dec.writeln('\t\tvmemcpy(&${prefix}${op}${c_name(field.name)}, (${field_type}*)${tmp}.data, sizeof(${field_type}));')
840-
} else {
841-
dec.writeln('\t\tvmemcpy(&${prefix}${op}${c_name(field.name)}, (${field_type}*)${tmp}.data, sizeof(${field_type}));')
842-
}
838+
dec.writeln('\t\tvmemcpy(&${prefix}${op}${c_name(field.name)}, (${field_type}*)${tmp}.data, sizeof(${field_type}));')
843839
} else {
844840
if field_sym.kind == .array_fixed {
845841
dec.writeln('\t\tvmemcpy(${prefix}${op}${c_name(field.name)},*(${field_type}*)${tmp}.data,sizeof(${field_type}));')
@@ -1022,7 +1018,7 @@ fn (mut g Gen) decode_array(utyp ast.Type, value_type ast.Type, fixed_array_size
10221018
if fixed_array_size > -1 {
10231019
fixed_array_idx += 'int fixed_array_idx = 0;'
10241020
array_element_assign += '((${styp}*)res.data)[fixed_array_idx] = val;'
1025-
fixed_array_idx_increment += 'fixed_array_idx++;'
1021+
fixed_array_idx_increment += 'fixed_array_idx++; res.state = 0;'
10261022
} else {
10271023
array_element_assign += 'array_push${noscan}((array*)&res.data, &val);'
10281024
res_str += '_option_ok(&(${g.base_type(utyp)}[]) { __new_array${noscan}(0, 0, sizeof(${styp})) }, (${option_name}*)&res, sizeof(${g.base_type(utyp)}));'

vlib/v/gen/c/str.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
234234
if temp_var_needed {
235235
g.write(tmp_var)
236236
} else {
237+
if expr is ast.StructInit && g.table.final_sym(expr.typ).is_primitive_fixed_array() {
238+
s := g.styp(expr.typ)
239+
g.write('(${s})')
240+
}
237241
g.expr_with_cast(expr, typ, typ)
238242
}
239243
} else if typ.has_flag(.option) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
type Arr = [4]u8
2+
type Arr2 = []u8
3+
type ArrStr = [4]string
4+
5+
fn test_main() {
6+
a := Arr{}
7+
b := Arr{}
8+
9+
assert a == b
10+
assert Arr{} == Arr{}
11+
assert Arr{} == [4]u8{}
12+
assert Arr{} == [u8(0), 0, 0, 0]!
13+
14+
assert Arr2{} == Arr2{}
15+
assert Arr2{} == []u8{}
16+
17+
assert ArrStr{} == ArrStr{}
18+
}

0 commit comments

Comments
 (0)