mirror of
https://github.com/vlang/v.git
synced 2025-09-11 00:20:26 -04:00
cgen: fix default T{}
when T
is ref type + dereferencing issue when comparing int alias to int (fix #22795) (#22807)
This commit is contained in:
parent
fdc49dc51a
commit
2e353d209d
@ -187,7 +187,7 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
|||||||
.alias {
|
.alias {
|
||||||
// optimize simple eq/ne operation on numbers
|
// optimize simple eq/ne operation on numbers
|
||||||
if left.unaliased_sym.is_int() {
|
if left.unaliased_sym.is_int() {
|
||||||
if left.typ.is_ptr() {
|
if left.typ.is_ptr() && node.left.is_auto_deref_var() && !right.typ.is_pointer() {
|
||||||
g.write('*'.repeat(left.typ.nr_muls()))
|
g.write('*'.repeat(left.typ.nr_muls()))
|
||||||
}
|
}
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
|
@ -64,6 +64,8 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
|||||||
if is_shared {
|
if is_shared {
|
||||||
typ = typ.clear_flag(.shared_f).set_nr_muls(0)
|
typ = typ.clear_flag(.shared_f).set_nr_muls(0)
|
||||||
}
|
}
|
||||||
|
// original is_ptr for the typ (aliased type could overwrite it)
|
||||||
|
is_ptr := typ.is_ptr()
|
||||||
mut sym := g.table.sym(typ)
|
mut sym := g.table.sym(typ)
|
||||||
// when type is non-option alias and doesn't has `str()`, print the aliased value
|
// when type is non-option alias and doesn't has `str()`, print the aliased value
|
||||||
if mut sym.info is ast.Alias && !sym.has_method('str') && !etype.has_flag(.option) {
|
if mut sym.info is ast.Alias && !sym.has_method('str') && !etype.has_flag(.option) {
|
||||||
@ -113,7 +115,6 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
|||||||
|| sym.kind in [.array, .array_fixed, .map, .struct, .multi_return, .sum_type, .interface] {
|
|| sym.kind in [.array, .array_fixed, .map, .struct, .multi_return, .sum_type, .interface] {
|
||||||
unwrap_option := expr is ast.Ident && expr.or_expr.kind == .propagate_option
|
unwrap_option := expr is ast.Ident && expr.or_expr.kind == .propagate_option
|
||||||
exp_typ := if unwrap_option { typ.clear_flag(.option) } else { typ }
|
exp_typ := if unwrap_option { typ.clear_flag(.option) } else { typ }
|
||||||
is_ptr := exp_typ.is_ptr()
|
|
||||||
is_dump_expr := expr is ast.DumpExpr
|
is_dump_expr := expr is ast.DumpExpr
|
||||||
is_var_mut := expr.is_auto_deref_var()
|
is_var_mut := expr.is_auto_deref_var()
|
||||||
str_fn_name := g.get_str_fn(exp_typ)
|
str_fn_name := g.get_str_fn(exp_typ)
|
||||||
@ -170,7 +171,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
|||||||
if sym.is_c_struct() {
|
if sym.is_c_struct() {
|
||||||
g.write(c_struct_ptr(sym, typ, str_method_expects_ptr))
|
g.write(c_struct_ptr(sym, typ, str_method_expects_ptr))
|
||||||
} else {
|
} else {
|
||||||
g.write('*'.repeat(typ.nr_muls()))
|
g.write('*'.repeat(etype.nr_muls()))
|
||||||
}
|
}
|
||||||
} else if sym.is_c_struct() {
|
} else if sym.is_c_struct() {
|
||||||
g.write(c_struct_ptr(sym, typ, str_method_expects_ptr))
|
g.write(c_struct_ptr(sym, typ, str_method_expects_ptr))
|
||||||
@ -201,7 +202,6 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
|||||||
g.write('}}}))')
|
g.write('}}}))')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
is_ptr := typ.is_ptr()
|
|
||||||
is_var_mut := expr.is_auto_deref_var()
|
is_var_mut := expr.is_auto_deref_var()
|
||||||
str_fn_name := g.get_str_fn(typ)
|
str_fn_name := g.get_str_fn(typ)
|
||||||
g.write('${str_fn_name}(')
|
g.write('${str_fn_name}(')
|
||||||
|
@ -37,9 +37,16 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
|
|||||||
g.go_back(3)
|
g.go_back(3)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mut sym := g.table.final_sym(g.unwrap_generic(node.typ))
|
unwrapped_typ := g.unwrap_generic(node.typ)
|
||||||
|
mut sym := g.table.final_sym(unwrapped_typ)
|
||||||
if sym.kind == .sum_type {
|
if sym.kind == .sum_type {
|
||||||
g.write(g.type_default_sumtype(g.unwrap_generic(node.typ), sym))
|
if node.typ.has_flag(.generic) && unwrapped_typ.is_ptr() {
|
||||||
|
g.write('&(')
|
||||||
|
g.write(g.type_default_sumtype(unwrapped_typ.set_nr_muls(0), sym))
|
||||||
|
g.write(')')
|
||||||
|
} else {
|
||||||
|
g.write(g.type_default_sumtype(unwrapped_typ, sym))
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
is_amp := g.is_amp
|
is_amp := g.is_amp
|
||||||
@ -120,7 +127,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
|
|||||||
} else {
|
} else {
|
||||||
// alias to pointer type
|
// alias to pointer type
|
||||||
if (g.table.sym(node.typ).kind == .alias && g.table.unaliased_type(node.typ).is_ptr())
|
if (g.table.sym(node.typ).kind == .alias && g.table.unaliased_type(node.typ).is_ptr())
|
||||||
|| (node.typ.has_flag(.generic) && g.unwrap_generic(node.typ).is_ptr()) {
|
|| (!sym.is_int() && node.typ.has_flag(.generic) && unwrapped_typ.is_ptr()) {
|
||||||
g.write('&')
|
g.write('&')
|
||||||
}
|
}
|
||||||
if is_array || const_msvc_init {
|
if is_array || const_msvc_init {
|
||||||
@ -349,10 +356,10 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
|
|||||||
g.fixed_array_init(ast.ArrayInit{
|
g.fixed_array_init(ast.ArrayInit{
|
||||||
pos: node.pos
|
pos: node.pos
|
||||||
is_fixed: true
|
is_fixed: true
|
||||||
typ: g.unwrap_generic(node.typ)
|
typ: unwrapped_typ
|
||||||
exprs: [ast.empty_expr]
|
exprs: [ast.empty_expr]
|
||||||
elem_type: arr_info.elem_type
|
elem_type: arr_info.elem_type
|
||||||
}, g.unwrap(g.unwrap_generic(node.typ)), '', g.is_amp)
|
}, g.unwrap(unwrapped_typ), '', g.is_amp)
|
||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
if is_multiline {
|
if is_multiline {
|
||||||
|
21
vlib/v/tests/generics/default_type_with_ref_test.v
Normal file
21
vlib/v/tests/generics/default_type_with_ref_test.v
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
struct Struct {}
|
||||||
|
|
||||||
|
type StructAlias = Struct
|
||||||
|
|
||||||
|
type SumType = Struct | int
|
||||||
|
|
||||||
|
type AliasInt = int
|
||||||
|
|
||||||
|
fn (d Struct) a[T]() T {
|
||||||
|
return T{}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
s := Struct{}
|
||||||
|
assert s.a[&int]() == 0
|
||||||
|
assert s.a[&int]() == unsafe { nil }
|
||||||
|
assert s.a[&Struct]() == Struct{}
|
||||||
|
assert s.a[&SumType]() is Struct
|
||||||
|
assert s.a[&StructAlias]() == StructAlias{}
|
||||||
|
assert s.a[&AliasInt]() == AliasInt(0)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user