autofree: fix frees before returns
parent
b9cbb4f177
commit
e86c6e024c
|
@ -4721,27 +4721,30 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
if expr is ast.Ident {
|
if expr is ast.Ident {
|
||||||
g.returned_var_name = expr.name
|
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
|
// free := g.is_autofree && !g.is_builtin_mod // node.exprs[0] is ast.CallExpr
|
||||||
// Create a temporary variable for the return expression
|
// Create a temporary variable for the return expression
|
||||||
free := !g.is_builtin_mod // node.exprs[0] is ast.CallExpr
|
mut gen_tmp_var := !g.is_builtin_mod // node.exprs[0] is ast.CallExpr
|
||||||
mut tmp := ''
|
mut tmp := ''
|
||||||
if free {
|
if gen_tmp_var {
|
||||||
// `return foo(a, b, c)`
|
// `return foo(a, b, c)`
|
||||||
// `tmp := foo(a, b, c); free(a); free(b); free(c); return tmp;`
|
// `tmp := foo(a, b, c); free(a); free(b); free(c); return tmp;`
|
||||||
// Save return value in a temp var so that 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`
|
// Don't use a tmp var if a variable is simply returned: `return x`
|
||||||
if node.exprs[0] !is ast.Ident {
|
if node.exprs[0] !is ast.Ident {
|
||||||
tmp = g.new_tmp_var()
|
tmp = g.new_tmp_var()
|
||||||
|
g.write('/*tmp return var*/ ')
|
||||||
g.write(g.typ(g.fn_decl.return_type))
|
g.write(g.typ(g.fn_decl.return_type))
|
||||||
g.write(' ')
|
g.write(' ')
|
||||||
g.write(tmp)
|
g.write(tmp)
|
||||||
g.write(' = ')
|
g.write(' = ')
|
||||||
} else {
|
} else {
|
||||||
|
gen_tmp_var = false
|
||||||
|
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||||
g.write('return ')
|
g.write('return ')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||||
g.write('return ')
|
g.write('return ')
|
||||||
}
|
}
|
||||||
if expr0.is_auto_deref_var() {
|
if expr0.is_auto_deref_var() {
|
||||||
|
@ -4755,10 +4758,11 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
} else {
|
} else {
|
||||||
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
|
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
|
||||||
}
|
}
|
||||||
if free {
|
if gen_tmp_var {
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
has_semicolon = true
|
has_semicolon = true
|
||||||
if tmp != '' {
|
if tmp != '' {
|
||||||
|
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||||
g.write('return $tmp')
|
g.write('return $tmp')
|
||||||
has_semicolon = false
|
has_semicolon = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
import strings
|
||||||
|
|
||||||
// This program is built and run via Valgrind to ensure there are no leaks with -autofree
|
// This program is built and run via Valgrind to ensure there are no leaks with -autofree
|
||||||
fn simple() {
|
fn simple() {
|
||||||
|
@ -341,6 +342,12 @@ fn comp_if() {
|
||||||
fn anon_fn() {
|
fn anon_fn() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn return_sb_str() string {
|
||||||
|
mut sb := strings.new_builder(100)
|
||||||
|
sb.write_string('hello')
|
||||||
|
return sb.str() // sb should be freed, but only after .str() is called
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println('start')
|
println('start')
|
||||||
simple()
|
simple()
|
||||||
|
@ -364,6 +371,7 @@ fn main() {
|
||||||
free_before_return()
|
free_before_return()
|
||||||
free_before_return_bool()
|
free_before_return_bool()
|
||||||
free_before_break()
|
free_before_break()
|
||||||
|
s := return_sb_str()
|
||||||
// free_map()
|
// free_map()
|
||||||
// loop_map()
|
// loop_map()
|
||||||
free_array_except_returned_element()
|
free_array_except_returned_element()
|
||||||
|
|
Loading…
Reference in New Issue