autofree: fix free before return
parent
88097125f7
commit
4e62bc0b81
|
@ -1768,7 +1768,7 @@ fn (mut g Gen) gen_asm_stmt(stmt ast.AsmStmt) {
|
|||
} else {
|
||||
g.write(' ')
|
||||
}
|
||||
// swap destionation and operands for att syntax
|
||||
// swap destionation and operands for att syntax
|
||||
if template.args.len != 0 {
|
||||
template.args.prepend(template.args[template.args.len - 1])
|
||||
template.args.delete(template.args.len - 1)
|
||||
|
@ -4539,7 +4539,7 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
|||
styp := g.typ(g.fn_decl.return_type)
|
||||
g.writeln('return ($styp){0};')
|
||||
} else {
|
||||
if g.is_autofree && !g.is_builtin_mod {
|
||||
if g.is_autofree {
|
||||
g.writeln('// free before return (no values returned)')
|
||||
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||
}
|
||||
|
@ -4680,13 +4680,24 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
|||
g.writeln('return $opt_tmp;')
|
||||
return
|
||||
}
|
||||
// autofree before `return`
|
||||
// set free_parent_scopes to true, since all variables defined in parent
|
||||
// scopes need to be freed before the return
|
||||
if g.is_autofree {
|
||||
expr := node.exprs[0]
|
||||
if expr is ast.Ident {
|
||||
g.returned_var_name = expr.name
|
||||
}
|
||||
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||
}
|
||||
// free := g.is_autofree && !g.is_builtin_mod // node.exprs[0] is ast.CallExpr
|
||||
// Create a temporary variable for the return expression
|
||||
free := !g.is_builtin_mod // node.exprs[0] is ast.CallExpr
|
||||
mut tmp := ''
|
||||
if free {
|
||||
// `return foo(a, b, c)`
|
||||
// `tmp := foo(a, b, c); free(a); free(b); free(c); return tmp;`
|
||||
// Save return value in a temp var so that it all args (a,b,c) can be freed
|
||||
// Save return value in a temp var so that all args (a,b,c) can be freed
|
||||
// Don't use a tmp var if a variable is simply returned: `return x`
|
||||
if node.exprs[0] !is ast.Ident {
|
||||
tmp = g.new_tmp_var()
|
||||
|
@ -4712,18 +4723,8 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
|||
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
|
||||
}
|
||||
if free {
|
||||
expr := node.exprs[0]
|
||||
if expr is ast.Ident {
|
||||
g.returned_var_name = expr.name
|
||||
}
|
||||
g.writeln(';')
|
||||
has_semicolon = true
|
||||
// autofree before `return`
|
||||
// set free_parent_scopes to true, since all variables defined in parent
|
||||
// scopes need to be freed before the return
|
||||
if g.pref.autofree {
|
||||
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||
}
|
||||
if tmp != '' {
|
||||
g.write('return $tmp')
|
||||
has_semicolon = false
|
||||
|
|
|
@ -318,6 +318,11 @@ fn get_user() User {
|
|||
return user
|
||||
}
|
||||
|
||||
fn get_user2() User {
|
||||
users := [User{'Peter', 25}, User{'Alice', 21}]
|
||||
return users[0] // has to be cloned, since `users` are going to be freed at the end of the function
|
||||
}
|
||||
|
||||
fn string_array_get() {
|
||||
s := ['a', 'b', 'c']
|
||||
x := s[0]
|
||||
|
@ -361,7 +366,7 @@ fn main() {
|
|||
free_before_break()
|
||||
// free_map()
|
||||
// loop_map()
|
||||
// free_array_except_returned_element()
|
||||
free_array_except_returned_element()
|
||||
println('end')
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue