autofree: fix re-assigning an optional
							parent
							
								
									f19ca6b411
								
							
						
					
					
						commit
						21002bf2de
					
				|  | @ -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 { | ||||
|  |  | |||
|  | @ -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);') | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue