mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
parent
8bb7f3dd75
commit
7dd91ecef7
5 changed files with 32 additions and 6 deletions
|
@ -289,6 +289,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||
|
||||
for i, mut left in node.left {
|
||||
mut is_auto_heap := false
|
||||
mut is_fn_var := false
|
||||
mut var_type := node.left_types[i]
|
||||
mut val_type := node.right_types[i]
|
||||
val := node.right[i]
|
||||
|
@ -432,6 +433,9 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||
}
|
||||
}
|
||||
is_auto_heap = left.obj.is_auto_heap
|
||||
if left.obj.typ != 0 && val is ast.PrefixExpr {
|
||||
is_fn_var = g.table.final_sym(left.obj.typ).kind == .function
|
||||
}
|
||||
}
|
||||
} else if mut left is ast.ComptimeSelector {
|
||||
if left.typ_key != '' {
|
||||
|
@ -964,14 +968,14 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||
} else {
|
||||
is_option_unwrapped := val is ast.Ident && val.or_expr.kind != .absent
|
||||
is_option_auto_heap := is_auto_heap && is_option_unwrapped
|
||||
if is_auto_heap {
|
||||
if is_auto_heap && !is_fn_var {
|
||||
if aligned != 0 {
|
||||
g.write('HEAP_align(${styp}, (')
|
||||
} else {
|
||||
g.write('HEAP(${styp}, (')
|
||||
}
|
||||
}
|
||||
if val.is_auto_deref_var() && !is_option_unwrapped {
|
||||
if !is_fn_var && val.is_auto_deref_var() && !is_option_unwrapped {
|
||||
g.write('*')
|
||||
}
|
||||
if (var_type.has_flag(.option) && val !in [ast.Ident, ast.SelectorExpr])
|
||||
|
@ -997,9 +1001,13 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||
g.fixed_array_var_init(tmp_var, false, unaliased_right_sym.info.elem_type,
|
||||
unaliased_right_sym.info.size)
|
||||
} else {
|
||||
old_inside_assign_fn_var := g.inside_assign_fn_var
|
||||
g.inside_assign_fn_var = val is ast.PrefixExpr && val.op == .amp
|
||||
&& is_fn_var
|
||||
g.expr(val)
|
||||
g.inside_assign_fn_var = old_inside_assign_fn_var
|
||||
}
|
||||
if is_auto_heap && !is_option_auto_heap {
|
||||
if !is_fn_var && is_auto_heap && !is_option_auto_heap {
|
||||
if aligned != 0 {
|
||||
g.write('), ${aligned})')
|
||||
} else {
|
||||
|
|
|
@ -163,6 +163,7 @@ mut:
|
|||
inside_cinit bool
|
||||
inside_global_decl bool
|
||||
inside_interface_deref bool
|
||||
inside_assign_fn_var bool
|
||||
last_tmp_call_var []string
|
||||
last_if_option_type ast.Type // stores the expected if type on nested if expr
|
||||
loop_depth int
|
||||
|
@ -5360,7 +5361,7 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||
if node.obj is ast.Var {
|
||||
is_auto_heap = node.obj.is_auto_heap
|
||||
&& (!g.is_assign_lhs || g.assign_op != .decl_assign)
|
||||
if is_auto_heap {
|
||||
if is_auto_heap && !g.inside_assign_fn_var {
|
||||
g.write('(*(')
|
||||
}
|
||||
is_option = is_option || node.obj.orig_type.has_flag(.option)
|
||||
|
@ -5478,7 +5479,7 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||
}
|
||||
g.write(')')
|
||||
}
|
||||
if is_auto_heap {
|
||||
if is_auto_heap && !g.inside_assign_fn_var {
|
||||
g.write('))')
|
||||
}
|
||||
return
|
||||
|
@ -5502,7 +5503,7 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||
}
|
||||
}
|
||||
g.write(g.get_ternary_name(name))
|
||||
if is_auto_heap {
|
||||
if is_auto_heap && !g.inside_assign_fn_var {
|
||||
g.write('))')
|
||||
if is_option && node.or_expr.kind != .absent {
|
||||
g.write('.data')
|
||||
|
|
2
vlib/v/gen/c/testdata/assign_fn_addr.c.must_have
vendored
Normal file
2
vlib/v/gen/c/testdata/assign_fn_addr.c.must_have
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
string (*cb2) (void) = &cb1;
|
||||
string (*cb3) (void) = &cb2;
|
3
vlib/v/gen/c/testdata/assign_fn_addr.out
vendored
Normal file
3
vlib/v/gen/c/testdata/assign_fn_addr.out
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
true
|
||||
true
|
||||
true
|
12
vlib/v/gen/c/testdata/assign_fn_addr.vv
vendored
Normal file
12
vlib/v/gen/c/testdata/assign_fn_addr.vv
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
const hello = 'hello world!'
|
||||
|
||||
fn main() {
|
||||
cb1 := fn () string {
|
||||
return hello
|
||||
}
|
||||
cb2 := &cb1
|
||||
cb3 := &cb2
|
||||
println(voidptr(cb1) != voidptr(cb2))
|
||||
println(voidptr(cb2) != voidptr(cb3))
|
||||
println(voidptr(cb1) != voidptr(cb3))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue