From 3164e29651d071e7b6a9f8ecbdc2302bd9f6e38f Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 12 Feb 2021 08:03:11 +0800 Subject: [PATCH] all: fix fn_or_for_in mut value (part 1) (#8671) --- vlib/v/ast/ast.v | 12 ++++++++++++ vlib/v/checker/checker.v | 18 +----------------- vlib/v/gen/c/cgen.v | 22 ++-------------------- vlib/v/gen/c/fn.v | 8 -------- vlib/v/gen/c/str.v | 3 +-- vlib/v/parser/fn.v | 1 + vlib/v/parser/for.v | 1 + 7 files changed, 18 insertions(+), 47 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 15cac308ef..21d2ea293f 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -434,6 +434,7 @@ pub: is_mut bool is_autofree_tmp bool is_arg bool // fn args should not be autofreed + is_auto_deref bool pub mut: typ table.Type orig_type table.Type // original sumtype type; 0 if it's not a sumtype @@ -1531,3 +1532,14 @@ pub struct Table { // pub mut: // main_fn_decl_node FnDecl } + +pub fn (expr Expr) is_mut_ident() bool { + if expr is Ident { + if expr.obj is Var { + if expr.obj.is_auto_deref { + return true + } + } + } + return false +} diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index ceabdefd87..1145ea12ba 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -68,8 +68,6 @@ mut: inside_sql bool // to handle sql table fields pseudo variables cur_orm_ts table.TypeSymbol error_details []string - for_in_mut_val_name string - fn_mut_arg_names []string vmod_file_content string // needed for @VMOD_FILE, contents of the file, *NOT its path** vweb_gen_types []table.Type // vweb route checks prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then @@ -2745,7 +2743,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { right.position()) } left_is_ptr := left_type.is_ptr() || left_sym.is_pointer() - if left_is_ptr && c.for_in_mut_val_name != left.str() && left.str() !in c.fn_mut_arg_names { + if left_is_ptr && !left.is_mut_ident() { if !c.inside_unsafe && assign_stmt.op !in [.assign, .decl_assign] { // ptr op= c.warn('pointer arithmetic is only allowed in `unsafe` blocks', assign_stmt.pos) @@ -3338,13 +3336,7 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { } } c.check_loop_label(node.label, node.pos) - if node.val_is_mut { - c.for_in_mut_val_name = node.val_var - } c.stmts(node.stmts) - if node.val_is_mut { - c.for_in_mut_val_name = '' - } c.loop_label = prev_loop_label c.in_for_count-- } @@ -5845,16 +5837,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { } } } - for param in node.params { - if param.is_mut { - c.fn_mut_arg_names << param.name - } - } c.fn_scope = node.scope c.stmts(node.stmts) - if c.fn_mut_arg_names.len > 0 { - c.fn_mut_arg_names.clear() - } node.has_return = c.returns || has_top_return(node.stmts) if node.language == .v && !node.no_body && node.return_type != table.void_type && !node.has_return && node.name !in ['panic', 'exit'] { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index ddd8029c02..68921b7c9d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -122,8 +122,6 @@ mut: strs_to_free0 []string // strings.Builder // strs_to_free []string // strings.Builder inside_call bool - for_in_mut_val_name string - fn_mut_arg_names []string has_main bool inside_const bool comp_for_method string // $for method in T.methods {} @@ -1418,13 +1416,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) { } g.writeln('DenseArray_value(&$atmp${arw_or_pt}key_values, $idx));') } - if it.val_is_mut { - g.for_in_mut_val_name = it.val_var - } g.stmts(it.stmts) - if it.val_is_mut { - g.for_in_mut_val_name = '' - } if it.key_type == table.string_type && !g.is_builtin_mod { // g.writeln('string_free(&$key);') } @@ -1471,13 +1463,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) { s := g.table.type_to_str(it.cond_type) g.error('for in: unhandled symbol `$it.cond` of type `$s`', it.pos) } - if it.val_is_mut { - g.for_in_mut_val_name = it.val_var - } g.stmts(it.stmts) - if it.val_is_mut { - g.for_in_mut_val_name = '' - } if it.label.len > 0 { g.writeln('\t${it.label}__continue: {}') } @@ -2046,9 +2032,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { g.array_set_pos = 0 } else { g.out.go_back_to(pos) - is_var_mut := !is_decl && left is ast.Ident - && (g.for_in_mut_val_name == (left as ast.Ident).name - || (left as ast.Ident).name in g.fn_mut_arg_names) + is_var_mut := !is_decl && left.is_mut_ident() addr := if is_var_mut { '' } else { '&' } g.writeln('') g.write('memcpy($addr') @@ -2119,9 +2103,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { g.prevent_sum_type_unwrapping_once = true } if !is_fixed_array_copy || is_decl { - if !is_decl && var_type != table.string_type_idx && left is ast.Ident - && (g.for_in_mut_val_name == (left as ast.Ident).name - || (left as ast.Ident).name in g.fn_mut_arg_names) { + if !is_decl && left.is_mut_ident() { g.write('*') } g.expr(left) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 184c64cf24..4f19c5b1ab 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -170,11 +170,6 @@ fn (mut g Gen) gen_fn_decl(node ast.FnDecl, skip bool) { g.definitions.write(fn_header) g.write(fn_header) } - for param in node.params { - if param.is_mut { - g.fn_mut_arg_names << param.name - } - } arg_start_pos := g.out.len fargs, fargtypes := g.fn_args(node.params, node.is_variadic) arg_str := g.out.after(arg_start_pos) @@ -223,9 +218,6 @@ fn (mut g Gen) gen_fn_decl(node ast.FnDecl, skip bool) { g.defer_stmts = [] g.stmts(node.stmts) // clear g.fn_mut_arg_names - if g.fn_mut_arg_names.len > 0 { - g.fn_mut_arg_names.clear() - } if !node.has_return { g.write_defer_stmts_when_needed() diff --git a/vlib/v/gen/c/str.v b/vlib/v/gen/c/str.v index 9ad908eb09..eb900a4adf 100644 --- a/vlib/v/gen/c/str.v +++ b/vlib/v/gen/c/str.v @@ -343,8 +343,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) { } else if sym_has_str_method || sym.kind in [.array, .array_fixed, .map, .struct_, .multi_return, .sum_type, .interface_] { is_ptr := typ.is_ptr() - is_var_mut := expr is ast.Ident && ((expr as ast.Ident).name == g.for_in_mut_val_name - || (expr as ast.Ident).name in g.fn_mut_arg_names) + is_var_mut := expr.is_mut_ident() str_fn_name := g.gen_str_for_type(typ) if is_ptr && !is_var_mut { g.write('_STR("&%.*s\\000", 2, ') diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 5fe81c0682..678b19b561 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -317,6 +317,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { name: param.name typ: param.typ is_mut: param.is_mut + is_auto_deref: param.is_mut pos: param.pos is_used: true is_arg: true diff --git a/vlib/v/parser/for.v b/vlib/v/parser/for.v index 175c8d50d5..41446a2a9a 100644 --- a/vlib/v/parser/for.v +++ b/vlib/v/parser/for.v @@ -157,6 +157,7 @@ fn (mut p Parser) for_stmt() ast.Stmt { name: val_var_name pos: val_var_pos is_mut: val_is_mut + is_auto_deref: val_is_mut is_tmp: true }) }