diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 9a73b6fc22..2db29903f5 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -766,12 +766,15 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) { // use the first stmt to get the scope stmt := stmts[0] // stmt := stmts[stmts.len-1] - if stmt !is ast.FnDecl { + if stmt !is ast.FnDecl && g.inside_ternary == 0 { // g.writeln('// autofree scope') // g.writeln('// autofree_scope_vars($stmt.position().pos) | ${typeof(stmt)}') // go back 1 position is important so we dont get the // internal scope of for loops and possibly other nodes - g.autofree_scope_vars(stmt.position().pos - 1) + // g.autofree_scope_vars(stmt.position().pos - 1) + stmt_pos := stmt.position() + g.writeln('// af scope_vars') + g.autofree_scope_vars(stmt_pos.pos - 1, stmt_pos.line_nr) } } } @@ -2022,7 +2025,7 @@ fn (mut g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, ad return true } -fn (mut g Gen) autofree_scope_vars(pos int) { +fn (mut g Gen) autofree_scope_vars(pos int, line_nr int) { if g.is_builtin_mod { // In `builtin` everything is freed manually. return @@ -2030,10 +2033,12 @@ fn (mut g Gen) autofree_scope_vars(pos int) { // eprintln('> free_scope_vars($pos)') scope := g.file.scope.innermost(pos) g.writeln('// autofree_scope_vars(pos=$pos scope.pos=$scope.start_pos scope.end_pos=$scope.end_pos)') - g.autofree_scope_vars2(scope, scope.end_pos) + // g.autofree_scope_vars2(scope, scope.end_pos) + g.autofree_scope_vars2(scope, scope.start_pos, scope.end_pos, line_nr) } -fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) { +// fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) { +fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int, line_nr int) { if isnil(scope) { return } @@ -2046,7 +2051,8 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) { // continue // } v := *obj - if v.pos.pos > end_pos { + // if v.pos.pos > end_pos { + if v.pos.pos > end_pos || (v.pos.pos < start_pos && v.pos.line_nr == line_nr) { // Do not free vars that were declared after this scope continue } @@ -2068,8 +2074,11 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) { // return // } // ``` + // if !isnil(scope.parent) && line_nr > 0 { if !isnil(scope.parent) { // g.autofree_scope_vars2(scope.parent, end_pos) + g.writeln('// af parent scope:') + // g.autofree_scope_vars2(scope.parent, start_pos, end_pos, line_nr) } } @@ -3415,6 +3424,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { g.writeln('$styp $tmp; /* if prepend */') } else if node.is_expr || g.inside_ternary != 0 { g.inside_ternary++ + // g.inside_if_expr = true g.write('(') for i, branch in node.branches { if i > 0 { @@ -3952,7 +3962,7 @@ fn (mut g Gen) return_statement(node ast.Return, af bool) { } if free { g.writeln('; // free tmp exprs') - g.autofree_scope_vars(node.pos.pos + 1) + g.autofree_scope_vars(node.pos.pos + 1, node.pos.line_nr) g.write('return $tmp') } } else { diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 564ccd8814..7cabd02fd6 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -155,7 +155,8 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) { // if g.autofree && !g.pref.experimental { // TODO: remove this, when g.write_autofree_stmts_when_needed works properly - g.autofree_scope_vars(it.body_pos.pos) + g.writeln('// af scope_vars (fn decl)') + g.autofree_scope_vars(it.body_pos.pos, it.body_pos.line_nr) } if it.return_type != table.void_type && it.stmts.len > 0 && it.stmts.last() !is ast.Return { default_expr := g.type_default(it.return_type)