Skip to content

Commit dd859ea

Browse files
authored
cgen: fix interface unsafe {nil} comparison and initialization (fix #24374) (#24411)
1 parent a412f53 commit dd859ea

File tree

5 files changed

+24
-2
lines changed

5 files changed

+24
-2
lines changed

vlib/v/gen/c/auto_eq_methods.v

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,13 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
258258
&& (!field.typ.has_flag(.option) || !field.typ.is_ptr()) {
259259
ptr := if field.typ.is_ptr() { '*'.repeat(field.typ.nr_muls()) } else { '' }
260260
eq_fn := g.gen_interface_equality_fn(field.typ)
261+
if ptr != '' {
262+
fn_builder.write_string('((${left_arg} == (void*)0 && ${right_arg} == (void*)0) || (${left_arg} != (void*)0 && ${right_arg} != (void*)0 && ')
263+
}
261264
fn_builder.write_string('${eq_fn}_interface_eq(${ptr}${left_arg}, ${ptr}${right_arg})')
265+
if ptr != '' {
266+
fn_builder.write_string('))')
267+
}
262268
} else if field.typ.has_flag(.option) {
263269
fn_builder.write_string('!memcmp(&${left_arg}.data, &${right_arg}.data, sizeof(${g.base_type(field.typ)}))')
264270
} else {

vlib/v/gen/c/cgen.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2786,6 +2786,9 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty
27862786
g.write('&(${exp_styp.trim_right('*')}){._${got_styp.trim_right('*')}=')
27872787
rparen_n = 0
27882788
mutable_idx = got.idx()
2789+
} else if expr is ast.UnsafeExpr && expr.expr is ast.Nil {
2790+
g.write('(void*)0')
2791+
return
27892792
} else {
27902793
g.write('HEAP(${exp_styp}, ${fname}(')
27912794
rparen_n++

vlib/v/tests/interfaces/interface_edge_cases/fn_returning_voidptr_casted_as_interface_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ fn test_fn_returning_voidptr_casted_as_interface_works() {
2323
// TODO: understand the root reason why msvc and
2424
// `-cc clang-11 -cflags -fsanitize=memory` produce
2525
// something like `&IAbc(e42aff650)` here
26-
assert f(pi).contains('&IAbc(')
26+
assert f(pi) == '&nil'
2727
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
interface Cfg {
2+
id string
3+
}
4+
5+
struct XX {
6+
cfg &Cfg = unsafe { nil }
7+
}
8+
9+
fn test_main() {
10+
xx := XX{}
11+
assert xx.cfg == unsafe { nil }
12+
assert unsafe { nil } == xx.cfg
13+
}

vlib/v/tests/structs/struct_init_with_interface_pointer_and_embed_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ fn test_struct_with_both_an_embed_and_a_pointer_to_interface_value_fields__initi
2424
assert si.contains('Embed: Embed{')
2525
assert si.contains('foo: 0')
2626
assert si.contains('id: 0')
27-
assert si.contains('parent: &Node(0x0)')
27+
assert si.contains('parent: &nil')
2828
assert si.contains('}')
2929
}

0 commit comments

Comments
 (0)