diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 5f4bcfd3f9..54f34a50aa 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -782,9 +782,25 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) { // 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) - stmt_pos := stmt.position() - g.writeln('// af scope_vars') - g.autofree_scope_vars(stmt_pos.pos - 1, stmt_pos.line_nr, false) + mut stmt_pos := stmt.position() + if stmt_pos.pos == 0 { + // Do not autofree if the position is 0, since the correct scope won't be found. + // Report a bug, since position shouldn't be 0 for most nodes. + if stmt is ast.Module { + return + } + if stmt is ast.ExprStmt { + // For some reason ExprStmt.pos is 0 when ExprStmt.expr is comp if expr + // Extract the pos. TODO figure out why and fix. + stmt_pos = stmt.expr.position() + } + if stmt_pos.pos == 0 { + print('autofree: first stmt pos = 0. ') + println(typeof(stmt)) + return + } + } + g.autofree_scope_vars(stmt_pos.pos, stmt_pos.line_nr, false) } } } diff --git a/vlib/v/parser/if_match.v b/vlib/v/parser/if_match.v index 710f7e9f73..d0cacaaf4a 100644 --- a/vlib/v/parser/if_match.v +++ b/vlib/v/parser/if_match.v @@ -18,7 +18,8 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr { pos := if is_comptime { p.inside_ct_if_expr = true p.next() // `$` - p.prev_tok.position().extend(p.tok.position()) + // p.prev_tok.position().extend(p.tok.position()) + p.tok.position() } else { p.tok.position() } diff --git a/vlib/v/tests/valgrind/1.strings_and_arrays.v b/vlib/v/tests/valgrind/1.strings_and_arrays.v index 13cec6eb18..e3ec0a5a98 100644 --- a/vlib/v/tests/valgrind/1.strings_and_arrays.v +++ b/vlib/v/tests/valgrind/1.strings_and_arrays.v @@ -278,6 +278,15 @@ fn string_array_get() { println(s) } +fn comp_if() { + // compif pos used to be 0, if it was the first statement in a block, vars wouldn't be freed + $if macos { + println('macos') + } + s := 'a' + 'b' + println(s) +} + fn main() { println('start') simple() @@ -297,6 +306,7 @@ fn main() { q := if_expr() s := return_if_expr() free_inside_opt_block() + comp_if() // free_before_return() // free_before_return_bool() // free_before_break()