1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: fix option ptr assignment (#18394)

This commit is contained in:
Felipe Pena 2023-06-10 18:53:35 -03:00 committed by GitHub
parent c4a20f0992
commit af8df871d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 2 deletions

View File

@ -1883,19 +1883,32 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
g.gen_option_error(ret_typ, expr) g.gen_option_error(ret_typ, expr)
g.writeln(';') g.writeln(';')
} else { } else {
mut is_ptr_to_ptr_assign := false
g.writeln('${g.typ(ret_typ)} ${tmp_var};') g.writeln('${g.typ(ret_typ)} ${tmp_var};')
if ret_typ.has_flag(.option) { if ret_typ.has_flag(.option) {
if expr_typ.has_flag(.option) && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] { if expr_typ.has_flag(.option) && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] {
g.write('_option_none(&(${styp}[]) { ') g.write('_option_none(&(${styp}[]) { ')
} else { } else {
g.write('_option_ok(&(${styp}[]) { ') is_ptr_to_ptr_assign = (expr is ast.SelectorExpr
|| (expr is ast.Ident && !(expr as ast.Ident).is_auto_heap()))
&& ret_typ.is_ptr() && expr_typ.is_ptr() && expr_typ.has_flag(.option)
// option ptr assignment simplification
if is_ptr_to_ptr_assign {
g.write('${tmp_var} = ')
} else {
g.write('_option_ok(&(${styp}[]) { ')
}
} }
} else { } else {
g.write('_result_ok(&(${styp}[]) { ') g.write('_result_ok(&(${styp}[]) { ')
} }
g.expr_with_cast(expr, expr_typ, ret_typ) g.expr_with_cast(expr, expr_typ, ret_typ)
if ret_typ.has_flag(.option) { if ret_typ.has_flag(.option) {
g.writeln(' }, (${c.option_name}*)(&${tmp_var}), sizeof(${styp}));') if is_ptr_to_ptr_assign {
g.writeln(';')
} else {
g.writeln(' }, (${c.option_name}*)(&${tmp_var}), sizeof(${styp}));')
}
} else { } else {
g.writeln(' }, (${c.result_name}*)(&${tmp_var}), sizeof(${styp}));') g.writeln(' }, (${c.result_name}*)(&${tmp_var}), sizeof(${styp}));')
} }

View File

@ -0,0 +1,20 @@
[heap]
struct Node[T] {
mut:
value T
next ?&Node[T]
}
fn print_t(node ?&Node[int]) ?&Node[int] {
println(node)
assert node == none
return node
}
fn test_main() {
n := Node[int]{
value: 5
}
t := print_t(n.next)
assert t == none
}