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

cgen: fix opt ptr argument passing with and without heap usage (#18423)

This commit is contained in:
Felipe Pena 2023-06-13 02:51:42 -03:00 committed by GitHub
parent 24c09881f7
commit ada702ec66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 7 deletions

View File

@ -7,12 +7,15 @@ import v.ast
import v.util
import v.token
fn (mut g Gen) expr_with_opt_or_block(expr ast.Expr, expr_typ ast.Type, var_expr ast.Expr, ret_typ ast.Type) {
fn (mut g Gen) expr_with_opt_or_block(expr ast.Expr, expr_typ ast.Type, var_expr ast.Expr, ret_typ ast.Type, in_heap bool) {
gen_or := expr is ast.Ident && (expr as ast.Ident).or_expr.kind != .absent
if gen_or {
old_inside_opt_or_res := g.inside_opt_or_res
g.inside_opt_or_res = true
g.expr_with_cast(expr, expr_typ, ret_typ)
if in_heap {
g.write('))')
}
g.writeln(';')
expr_var := if expr is ast.Ident && (expr as ast.Ident).is_auto_heap() {
'(*${expr.name})'
@ -575,7 +578,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.write('${styp} ')
}
}
if is_auto_heap {
if is_auto_heap && !(val_type.is_ptr() && val_type.has_flag(.option)) {
g.write('*')
}
}
@ -665,15 +668,18 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.write('{0}')
}
} else {
is_option_unwrapped := (val is ast.Ident
&& (val as ast.Ident).or_expr.kind != .absent)
is_option_auto_heap := is_auto_heap && is_option_unwrapped
if is_auto_heap {
g.write('HEAP(${styp}, (')
}
if val.is_auto_deref_var() {
if val.is_auto_deref_var() && !is_option_unwrapped {
g.write('*')
}
if (var_type.has_flag(.option) && val !in [ast.Ident, ast.SelectorExpr])
|| gen_or {
g.expr_with_opt_or_block(val, val_type, left, var_type)
g.expr_with_opt_or_block(val, val_type, left, var_type, is_option_auto_heap)
} else if val is ast.ArrayInit {
g.array_init(val, c_name(ident.name))
} else if val_type.has_flag(.shared_f) {
@ -681,7 +687,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
} else {
g.expr(val)
}
if is_auto_heap {
if is_auto_heap && !is_option_auto_heap {
g.write('))')
}
}
@ -695,7 +701,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.is_option_auto_heap = old_is_auto_heap
}
if var_type.has_flag(.option) || gen_or {
g.expr_with_opt_or_block(val, val_type, left, var_type)
g.expr_with_opt_or_block(val, val_type, left, var_type, false)
} else if node.has_cross_var {
g.gen_cross_tmp_variable(node.left, val)
} else {

View File

@ -1898,6 +1898,9 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
} else {
g.write('_option_ok(&(${styp}[]) { ')
}
if !expr_typ.is_ptr() && ret_typ.is_ptr() {
g.write('&/*ref*/')
}
}
} else {
g.write('_result_ok(&(${styp}[]) { ')

View File

@ -2193,7 +2193,12 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
if arg_typ_sym.kind != .function && deref_sym.kind !in [.sum_type, .interface_]
&& lang != .c {
if arg.expr.is_lvalue() {
g.write('(voidptr)&/*qq*/')
if expected_type.has_flag(.option) {
g.expr_with_opt(arg.expr, arg_typ, expected_type)
return
} else {
g.write('(voidptr)&/*qq*/')
}
} else {
mut atype := expected_deref_type
if atype.has_flag(.generic) {

View File

@ -0,0 +1,25 @@
module main
[heap]
struct Node[T] {
mut:
value T
next ?&Node[T]
}
fn print_t1(node ?&Node[int]) {
println(node)
}
fn print_t2(mut node ?&Node[int]) {
n := node or { return }
println(n)
}
fn test_main() {
mut n := Node[int]{
value: 5
}
print_t1(n)
print_t2(mut n.next)
}

View File

@ -0,0 +1,24 @@
module main
struct Node[T] {
mut:
value T
next ?&Node[T]
}
fn print_t1(node ?&Node[int]) {
println(node)
}
fn print_t2(mut node ?&Node[int]) {
n := node or { return }
println(n)
}
fn test_main() {
mut n := Node[int]{
value: 5
}
print_t1(n)
print_t2(mut n.next)
}