From c0fde9ff66656d9d1d551db82bb787304536e9f7 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 3 Nov 2024 17:26:17 -0300 Subject: [PATCH 1/4] fix --- vlib/v/gen/c/fn.v | 22 +++++++++++++++++++ vlib/v/tests/fns/diff_indirections_arg_test.v | 12 ++++++++++ 2 files changed, 34 insertions(+) create mode 100644 vlib/v/tests/fns/diff_indirections_arg_test.v diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 0f9d32a00edc81..20490c9bf8a38f 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2740,6 +2740,22 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) { } } +// gen_tmp_var_indirections generates tmp var to fit the expected indirection number +fn (mut g Gen) gen_tmp_var_indirections(var_typ ast.Type, var_name string, nindirections int) { + mut last_var := var_name + var_styp := g.styp(var_typ) + line := g.go_before_last_stmt() + g.empty_line = true + for i in 0 .. nindirections { + tmp_var := g.new_tmp_var() + ptr := '*'.repeat(i + 1) + g.writeln('${var_styp} ${ptr}${tmp_var} = &${last_var};') + last_var = tmp_var + } + g.write(line) + g.write(last_var) +} + @[inline] fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language, is_smartcast bool) { arg_typ := if arg.expr is ast.ComptimeSelector { @@ -2818,6 +2834,12 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as } else if !(!arg.is_mut && arg_sym.kind == .alias && g.table.unaliased_type(arg_typ).is_any_kind_of_pointer()) { g.write('(voidptr)&/*qq*/') + if arg.expr is ast.Ident + && expected_type.nr_muls() > (arg_typ.nr_muls() + 1) { + // generates temporary vars for fit the expected indirections + g.gen_tmp_var_indirections(arg_typ, arg.expr.name, expected_type.nr_muls() - arg_typ.nr_muls() - 1) + return + } } } else { mut atype := expected_deref_type diff --git a/vlib/v/tests/fns/diff_indirections_arg_test.v b/vlib/v/tests/fns/diff_indirections_arg_test.v new file mode 100644 index 00000000000000..34ac537cc1beb3 --- /dev/null +++ b/vlib/v/tests/fns/diff_indirections_arg_test.v @@ -0,0 +1,12 @@ +fn takes_ref(x &&&&int) { + unsafe { + ****x = 5 + } +} + +fn test_main() { + y := 4 + takes_ref(y) + println(y) + assert y == 5 +} From fb037c077a732e55787c97872e7546f1ae39bae5 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 3 Nov 2024 17:29:13 -0300 Subject: [PATCH 2/4] fix --- vlib/v/gen/c/fn.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 20490c9bf8a38f..30d3a97cd49eb0 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2744,7 +2744,7 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) { fn (mut g Gen) gen_tmp_var_indirections(var_typ ast.Type, var_name string, nindirections int) { mut last_var := var_name var_styp := g.styp(var_typ) - line := g.go_before_last_stmt() + line := g.go_before_last_stmt().trim_space() g.empty_line = true for i in 0 .. nindirections { tmp_var := g.new_tmp_var() From 8f851bcb6267a3c8f1bfe210210b09eaa5b25ffd Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 4 Nov 2024 07:45:03 -0300 Subject: [PATCH 3/4] fix --- vlib/v/ast/ast.v | 3 ++- vlib/v/gen/c/fn.v | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index d8e423c51fc81d..6026ca0ac51369 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -2205,7 +2205,8 @@ pub fn (expr Expr) pos() token.Pos { pub fn (expr Expr) is_lvalue() bool { return match expr { - Ident, CTempVar { true } + Ident { expr.kind != .constant } + CTempVar { true } IndexExpr { expr.left.is_lvalue() } SelectorExpr { expr.expr.is_lvalue() } ParExpr { expr.expr.is_lvalue() } // for var := &{...(*pointer_var)} diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 30d3a97cd49eb0..529b559c53e1a0 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2741,16 +2741,17 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) { } // gen_tmp_var_indirections generates tmp var to fit the expected indirection number -fn (mut g Gen) gen_tmp_var_indirections(var_typ ast.Type, var_name string, nindirections int) { - mut last_var := var_name +fn (mut g Gen) gen_tmp_var_indirections(var_typ ast.Type, var ast.Ident, nindirections int) { + mut last_var := g.expr_string(var) var_styp := g.styp(var_typ) line := g.go_before_last_stmt().trim_space() g.empty_line = true + tmp_var := g.new_tmp_var() for i in 0 .. nindirections { - tmp_var := g.new_tmp_var() - ptr := '*'.repeat(i + 1) - g.writeln('${var_styp} ${ptr}${tmp_var} = &${last_var};') - last_var = tmp_var + ptr := '*'.repeat(i) + tmp_var_v := if i == 0 { tmp_var } else { '${tmp_var}_${i}' } + g.writeln('${var_styp} *${ptr}${tmp_var_v} = &${last_var};') + last_var = tmp_var_v } g.write(line) g.write(last_var) @@ -2834,10 +2835,10 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as } else if !(!arg.is_mut && arg_sym.kind == .alias && g.table.unaliased_type(arg_typ).is_any_kind_of_pointer()) { g.write('(voidptr)&/*qq*/') - if arg.expr is ast.Ident + if arg.expr.is_lvalue() && arg.expr is ast.Ident && expected_type.nr_muls() > (arg_typ.nr_muls() + 1) { // generates temporary vars for fit the expected indirections - g.gen_tmp_var_indirections(arg_typ, arg.expr.name, expected_type.nr_muls() - arg_typ.nr_muls() - 1) + g.gen_tmp_var_indirections(arg_typ, arg.expr, expected_type.nr_muls() - arg_typ.nr_muls() - 1) return } } From 4be924801ec619a2f07de6efe363ad20289ef90a Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 4 Nov 2024 07:48:14 -0300 Subject: [PATCH 4/4] fix --- vlib/v/ast/ast.v | 3 +-- vlib/v/gen/c/fn.v | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 6026ca0ac51369..d8e423c51fc81d 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -2205,8 +2205,7 @@ pub fn (expr Expr) pos() token.Pos { pub fn (expr Expr) is_lvalue() bool { return match expr { - Ident { expr.kind != .constant } - CTempVar { true } + Ident, CTempVar { true } IndexExpr { expr.left.is_lvalue() } SelectorExpr { expr.expr.is_lvalue() } ParExpr { expr.expr.is_lvalue() } // for var := &{...(*pointer_var)} diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 529b559c53e1a0..025721b866c80f 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2835,7 +2835,7 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as } else if !(!arg.is_mut && arg_sym.kind == .alias && g.table.unaliased_type(arg_typ).is_any_kind_of_pointer()) { g.write('(voidptr)&/*qq*/') - if arg.expr.is_lvalue() && arg.expr is ast.Ident + if arg.expr is ast.Ident && arg.expr.kind != .constant && expected_type.nr_muls() > (arg_typ.nr_muls() + 1) { // generates temporary vars for fit the expected indirections g.gen_tmp_var_indirections(arg_typ, arg.expr, expected_type.nr_muls() - arg_typ.nr_muls() - 1)