diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 89385cd166..0a5de1efc6 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1433,8 +1433,9 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { // int pos = *(int*)_t190.data; mut gen_or := false mut tmp_opt := '' - is_optional := g.pref.autofree && assign_stmt.op == .decl_assign && assign_stmt.left_types.len == - 1 && assign_stmt.right[0] is ast.CallExpr + is_optional := g.pref.autofree && + (assign_stmt.op in [.decl_assign, .assign]) && assign_stmt.left_types.len == 1 && assign_stmt.right[0] is + ast.CallExpr if is_optional { // g.write('/* optional assignment */') call_expr := assign_stmt.right[0] as ast.CallExpr @@ -1726,7 +1727,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { // `int pos = *(int)_t10.data;` g.write('*($styp*)') if g.pref.autofree { - g.write(tmp_opt + '.data/*FF*/') + g.write(tmp_opt + '.data/*FFz*/') g.right_is_opt = false g.is_assign_rhs = false if g.inside_ternary == 0 && !assign_stmt.is_simple { diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 6e49c70b15..39a2672ec9 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -15,11 +15,6 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) { // || it.no_body { return } - if g.pref.autofree { - defer { - // g.autofree_tmp_vars = [] - } - } // if g.fileis('vweb.v') { // println('\ngen_fn_decl() $it.name $it.is_generic $g.cur_generic_type') // } @@ -661,12 +656,11 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) { // t := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i' t := '_arg_expr_${fn_name}_$i' // g.called_fn_name = name - // used := t in g.autofree_tmp_vars used := scope.known_var(t) mut s := '' if used { // This means this tmp var name was already used (the same function was called and - // `_arg_fnname_1` was already generated. + // `_arg_fnname_1` was already generated). // We do not need to declare this variable again, so just generate `t = ...` // instead of `string t = ...`, and we need to mark this variable as unused, // so that it's freed after the call. (Used tmp arg vars are not freed to avoid double frees). @@ -684,7 +678,6 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) { is_autofree_tmp: true }) s = 'string $t = ' - // g.autofree_tmp_vars << t } // g.expr(arg.expr) s += g.write_expr_to_string(arg.expr) @@ -707,7 +700,7 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) { if g.nr_vars_to_free <= 0 { return } - g.writeln('\n// strs_to_free3:') + // g.writeln('\n/* strs_to_free3: */') /* for s in g.strs_to_free { g.writeln('string_free(&$s);') diff --git a/vlib/v/tests/valgrind/1.strings_and_arrays.v b/vlib/v/tests/valgrind/1.strings_and_arrays.v index 570d05552d..6d495864c3 100644 --- a/vlib/v/tests/valgrind/1.strings_and_arrays.v +++ b/vlib/v/tests/valgrind/1.strings_and_arrays.v @@ -119,6 +119,14 @@ fn optional_str() { return } println(pos + 1) + // + mut p := 0 + for { + p = opt('foo') or { + break + } + break + } } fn return_error_with_freed_expr() ?string {