From 507d724ee6440648ede729633f8031c86486f620 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 9 Nov 2020 11:54:41 +0100 Subject: [PATCH] autofree: free before return tests --- vlib/os/os_nix.c.v | 3 +++ vlib/v/gen/cgen.v | 11 ++++++----- vlib/v/gen/fn.v | 3 ++- vlib/v/tests/valgrind/1.strings_and_arrays.v | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 7c44662ea6..1b247ca813 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -110,6 +110,9 @@ pub fn mkdir(path string) ?bool { } */ apath := real_path(path) + defer { + apath.free() + } /* $if linux { $if !android { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index ab797017b0..817d99f5d9 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1003,11 +1003,12 @@ fn (mut g Gen) stmt(node ast.Stmt) { af := g.pref.autofree && node.exprs.len > 0 && node.exprs[0] is ast.CallExpr && !g.is_builtin_mod if g.pref.autofree { g.writeln('// ast.Return free') - // if af { - // g.autofree_call_pregen(node.exprs[0] as ast.CallExpr) - // } - // g.autofree_scope_vars(node.pos.pos) - g.write_autofree_stmts_when_needed(node) + if af { + g.writeln('//af tmp') + // g.autofree_call_pregen(node.exprs[0] as ast.CallExpr) + } + // g.autofree_scope_vars(node.pos.pos - 1) + // g.write_autofree_stmts_when_needed(node) } g.return_statement(node, af) } diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 2f773835b4..eebfdff8c3 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -186,6 +186,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) { } } +/* fn (mut g Gen) write_autofree_stmts_when_needed(r ast.Return) { // TODO: write_autofree_stmts_when_needed should account for the current local scope vars. // TODO: write_autofree_stmts_when_needed should not free the returned variables. @@ -195,7 +196,7 @@ fn (mut g Gen) write_autofree_stmts_when_needed(r ast.Return) { // g.writeln(g.autofree_scope_vars(g.fn_decl.body_pos.pos)) // g.writeln('//--------------------------------------------------- ') // //g.write( g.autofree_scope_vars(r.pos.pos) ) } - +*/ fn (mut g Gen) write_defer_stmts_when_needed() { if g.defer_stmts.len > 0 { g.write_defer_stmts() diff --git a/vlib/v/tests/valgrind/1.strings_and_arrays.v b/vlib/v/tests/valgrind/1.strings_and_arrays.v index 884aa3e51f..238966ca66 100644 --- a/vlib/v/tests/valgrind/1.strings_and_arrays.v +++ b/vlib/v/tests/valgrind/1.strings_and_arrays.v @@ -1,3 +1,5 @@ +import os + // This program is built and run via Valgrind to ensure there are no leaks with -autofree fn simple() { nums := [1, 2, 3] // local array must be freed @@ -218,6 +220,20 @@ fn free_inside_opt_block() { } } +fn free_before_return() { + s := 'a' + 'b' + println(s) + if true { + return + } +} + +fn free_before_return_bool() bool { + s := 'a' + 'b' + println(s) + return true +} + fn main() { println('start') simple() @@ -236,6 +252,8 @@ fn main() { q := if_expr() s := return_if_expr() free_inside_opt_block() + // free_before_return() + // free_before_return_bool() // free_map() // loop_map() println('end')