From 8eff8b0eff9b6eb591be3fcf24570b903bf02097 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 6 Dec 2020 08:38:21 +0100 Subject: [PATCH] autofree: fix `for` args --- vlib/v/ast/ast.v | 3 ++- vlib/v/gen/cgen.v | 7 ++++++- vlib/v/parser/for.v | 3 +++ vlib/v/tests/valgrind/1.strings_and_arrays.v | 5 +++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index c188977521..ca59f289a8 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -368,8 +368,9 @@ pub mut: pos token.Position is_used bool is_changed bool // to detect mutable vars that are never changed - is_or bool // `x := foo() or { ... }` + // // (for setting the position after the or block for autofree) + is_or bool // `x := foo() or { ... }` is_tmp bool // for tmp for loop vars, so that autofree can skip them } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 89cee85faa..e56bde4801 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2099,9 +2099,14 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int continue } if obj.is_or { - g.writeln('// skipping `or{}` var "$obj.name"') // Skip vars inited with the `or {}`, since they are generated // after the or block in C. + g.writeln('// skipping `or{}` var "$obj.name"') + continue + } + if obj.is_tmp { + // Skip for loop vars + g.writeln('// skipping tmp var "$obj.name"') continue } // if var.typ == 0 { diff --git a/vlib/v/parser/for.v b/vlib/v/parser/for.v index 924faf5925..d0f56c3efe 100644 --- a/vlib/v/parser/for.v +++ b/vlib/v/parser/for.v @@ -104,6 +104,7 @@ fn (mut p Parser) for_stmt() ast.Stmt { name: key_var_name typ: table.int_type pos: key_var_pos + is_tmp: true }) } else if p.scope.known_var(val_var_name) { p.error('redefinition of value iteration variable `$val_var_name`') @@ -129,6 +130,7 @@ fn (mut p Parser) for_stmt() ast.Stmt { name: val_var_name typ: table.int_type pos: val_var_pos + is_tmp: true }) if key_var_name.len > 0 { p.error_with_pos('cannot declare index variable with range `for`', key_var_pos) @@ -140,6 +142,7 @@ fn (mut p Parser) for_stmt() ast.Stmt { name: val_var_name pos: val_var_pos is_mut: val_is_mut + is_tmp: true }) } p.inside_for = false diff --git a/vlib/v/tests/valgrind/1.strings_and_arrays.v b/vlib/v/tests/valgrind/1.strings_and_arrays.v index 41b4985376..1a8942fcc9 100644 --- a/vlib/v/tests/valgrind/1.strings_and_arrays.v +++ b/vlib/v/tests/valgrind/1.strings_and_arrays.v @@ -294,6 +294,11 @@ fn free_before_break() { continue } } + x := ['1', '2', '3'] + for n in x { + f := 'f' + println('$n => $f') + } } struct User {