mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
fix
This commit is contained in:
parent
24f91280d9
commit
7f402b3e1c
3 changed files with 28 additions and 10 deletions
|
@ -62,7 +62,7 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int
|
||||||
match obj {
|
match obj {
|
||||||
ast.Var {
|
ast.Var {
|
||||||
g.trace_autofree('// var "${obj.name}" var.pos=${obj.pos.pos} var.line_nr=${obj.pos.line_nr}')
|
g.trace_autofree('// var "${obj.name}" var.pos=${obj.pos.pos} var.line_nr=${obj.pos.line_nr}')
|
||||||
if obj.name == g.returned_var_name {
|
if obj.name in g.returned_var_names {
|
||||||
g.print_autofree_var(obj, 'returned from function')
|
g.print_autofree_var(obj, 'returned from function')
|
||||||
g.trace_autofree('// skipping returned var')
|
g.trace_autofree('// skipping returned var')
|
||||||
continue
|
continue
|
||||||
|
@ -247,3 +247,17 @@ fn (mut g Gen) autofree_var_call(free_fn_name string, v ast.Var) {
|
||||||
}
|
}
|
||||||
g.autofree_scope_stmts << af.str()
|
g.autofree_scope_stmts << af.str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) detect_used_var_on_return(expr ast.Expr) {
|
||||||
|
match expr {
|
||||||
|
ast.Ident {
|
||||||
|
g.returned_var_names[expr.name] = true
|
||||||
|
}
|
||||||
|
ast.StructInit {
|
||||||
|
for field_expr in expr.init_fields {
|
||||||
|
g.detect_used_var_on_return(field_expr.expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -231,11 +231,11 @@ mut:
|
||||||
// where an aggregate (at least two types) is generated
|
// where an aggregate (at least two types) is generated
|
||||||
// sum type deref needs to know which index to deref because unions take care of the correct field
|
// sum type deref needs to know which index to deref because unions take care of the correct field
|
||||||
aggregate_type_idx int
|
aggregate_type_idx int
|
||||||
arg_no_auto_deref bool // smartcast must not be dereferenced
|
arg_no_auto_deref bool // smartcast must not be dereferenced
|
||||||
branch_parent_pos int // used in BranchStmt (continue/break) for autofree stop position
|
branch_parent_pos int // used in BranchStmt (continue/break) for autofree stop position
|
||||||
returned_var_name string // to detect that a var doesn't need to be freed since it's being returned
|
returned_var_names map[string]bool // to detect that vars doesn't need to be freed since it's being returned
|
||||||
infix_left_var_name string // a && if expr
|
infix_left_var_name string // a && if expr
|
||||||
curr_var_name []string // curr var name on assignment
|
curr_var_name []string // curr var name on assignment
|
||||||
called_fn_name string
|
called_fn_name string
|
||||||
timers &util.Timers = util.get_timers()
|
timers &util.Timers = util.get_timers()
|
||||||
force_main_console bool // true when @[console] used on fn main()
|
force_main_console bool // true when @[console] used on fn main()
|
||||||
|
@ -6241,6 +6241,9 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||||
g.writeln(' }, (${option_name}*)(&${tmpvar}), sizeof(${styp}));')
|
g.writeln(' }, (${option_name}*)(&${tmpvar}), sizeof(${styp}));')
|
||||||
}
|
}
|
||||||
g.write_defer_stmts_when_needed()
|
g.write_defer_stmts_when_needed()
|
||||||
|
if g.is_autofree {
|
||||||
|
g.detect_used_var_on_return(expr0)
|
||||||
|
}
|
||||||
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||||
g.writeln('return ${tmpvar};')
|
g.writeln('return ${tmpvar};')
|
||||||
return
|
return
|
||||||
|
@ -6286,6 +6289,9 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||||
g.writeln(' }, (${result_name}*)(&${tmpvar}), sizeof(${styp}));')
|
g.writeln(' }, (${result_name}*)(&${tmpvar}), sizeof(${styp}));')
|
||||||
}
|
}
|
||||||
g.write_defer_stmts_when_needed()
|
g.write_defer_stmts_when_needed()
|
||||||
|
if g.is_autofree {
|
||||||
|
g.detect_used_var_on_return(expr0)
|
||||||
|
}
|
||||||
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||||
g.writeln('return ${tmpvar};')
|
g.writeln('return ${tmpvar};')
|
||||||
return
|
return
|
||||||
|
@ -6294,9 +6300,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||||
// set free_parent_scopes to true, since all variables defined in parent
|
// set free_parent_scopes to true, since all variables defined in parent
|
||||||
// scopes need to be freed before the return
|
// scopes need to be freed before the return
|
||||||
if g.is_autofree {
|
if g.is_autofree {
|
||||||
if expr0 is ast.Ident {
|
g.detect_used_var_on_return(expr0)
|
||||||
g.returned_var_name = expr0.name
|
|
||||||
}
|
|
||||||
if !use_tmp_var && !g.is_builtin_mod {
|
if !use_tmp_var && !g.is_builtin_mod {
|
||||||
use_tmp_var = expr0 is ast.CallExpr
|
use_tmp_var = expr0 is ast.CallExpr
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.returned_var_name = ''
|
g.returned_var_names.clear()
|
||||||
old_g_autofree := g.is_autofree
|
old_g_autofree := g.is_autofree
|
||||||
if node.is_manualfree {
|
if node.is_manualfree {
|
||||||
g.is_autofree = false
|
g.is_autofree = false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue