From 4eb087a34755d0b184e6c13b34e25f1c89d9273a Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 14 Sep 2024 17:13:25 -0300 Subject: [PATCH] checker: add missing check for ref passing to non-ref (#22194) --- .../path_finding_algorithm_visualizer/aStar.v | 4 ++-- .../ed25519/internal/edwards25519/element.v | 2 +- .../ed25519/internal/edwards25519/extra.v | 2 +- .../ed25519/internal/edwards25519/point.v | 8 ++++---- .../ed25519/internal/edwards25519/table.v | 2 +- vlib/net/tcp.c.v | 4 ++-- vlib/net/unix/stream.c.v | 2 +- vlib/v/ast/ast.v | 17 +++++++++++++++++ vlib/v/checker/check_types.v | 6 ++++++ vlib/v/checker/tests/ref_to_non_ref_err.out | 5 +++++ vlib/v/checker/tests/ref_to_non_ref_err.vv | 10 ++++++++++ vlib/v/gen/c/fn.v | 2 ++ vlib/v/gen/js/array.v | 4 ++-- 13 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 vlib/v/checker/tests/ref_to_non_ref_err.out create mode 100644 vlib/v/checker/tests/ref_to_non_ref_err.vv diff --git a/examples/gg/path_finding_algorithm_visualizer/aStar.v b/examples/gg/path_finding_algorithm_visualizer/aStar.v index 9f0a46327302ef..f39700ae9017c8 100644 --- a/examples/gg/path_finding_algorithm_visualizer/aStar.v +++ b/examples/gg/path_finding_algorithm_visualizer/aStar.v @@ -329,7 +329,7 @@ fn astar_path_finding(mut app App, mut grid [][]Cell, start Point, end Point) { g_score[start.x][start.y] = 0 f_score[start.x][start.y] = g_score[start.x][start.y] + hf(start, end) - priority_queue.insert(&Node{ + priority_queue.insert(Node{ f_score: f_score[start.x][start.y] cell: &Point{ x: start.x @@ -360,7 +360,7 @@ fn astar_path_finding(mut app App, mut grid [][]Cell, start Point, end Point) { if temp_g_score < g_score[neighbor.x][neighbor.y] { g_score[neighbor.x][neighbor.y] = temp_g_score if !(neighbor.x == start.x && neighbor.y == start.y) { - priority_queue.insert(&Node{ + priority_queue.insert(Node{ f_score: g_score[neighbor.x][neighbor.y] + hf(neighbor, end) cell: neighbor count: curr_node.count + 1 diff --git a/vlib/crypto/ed25519/internal/edwards25519/element.v b/vlib/crypto/ed25519/internal/edwards25519/element.v index 5f88a936df8fdc..3197e5edacfa33 100644 --- a/vlib/crypto/ed25519/internal/edwards25519/element.v +++ b/vlib/crypto/ed25519/internal/edwards25519/element.v @@ -538,7 +538,7 @@ pub fn (mut v Element) pow_22523(x Element) Element { for i := 1; i < 100; i++ { // 2^200 - 2^100 t2.square(t2) } - t1.multiply(t2, &t1) // 2^200 - 1 + t1.multiply(t2, t1) // 2^200 - 1 t1.square(t1) // 2^201 - 2 for i := 1; i < 50; i++ { // 2^250 - 2^50 t1.square(t1) diff --git a/vlib/crypto/ed25519/internal/edwards25519/extra.v b/vlib/crypto/ed25519/internal/edwards25519/extra.v index 4f171caa6c74b2..c68445f0453cca 100644 --- a/vlib/crypto/ed25519/internal/edwards25519/extra.v +++ b/vlib/crypto/ed25519/internal/edwards25519/extra.v @@ -108,7 +108,7 @@ fn (mut v Point) bytes_montgomery_generic(mut buf [32]u8) []u8 { mut u := Element{} y.multiply(v.y, y.invert(v.z)) // y = Y / Z - recip.invert(recip.subtract(fe_one, &y)) // r = 1/(1 - y) + recip.invert(recip.subtract(fe_one, y)) // r = 1/(1 - y) u.multiply(u.add(fe_one, y), recip) // u = (1 + y)*r return copy_field_element(mut buf, mut u) diff --git a/vlib/crypto/ed25519/internal/edwards25519/point.v b/vlib/crypto/ed25519/internal/edwards25519/point.v index 3b1f0775308da3..4661ed8c9b791e 100644 --- a/vlib/crypto/ed25519/internal/edwards25519/point.v +++ b/vlib/crypto/ed25519/internal/edwards25519/point.v @@ -353,8 +353,8 @@ fn (mut v ProjectiveP1) sub(p Point, q ProjectiveCached) ProjectiveP1 { ypx.add(p.y, p.x) ymx.subtract(p.y, p.x) - pp.multiply(&ypx, q.ymx) // flipped sign - mm.multiply(&ymx, q.ypx) // flipped sign + pp.multiply(ypx, q.ymx) // flipped sign + mm.multiply(ymx, q.ypx) // flipped sign tt2d.multiply(p.t, q.t2d) zz2.multiply(p.z, q.z) @@ -378,8 +378,8 @@ fn (mut v ProjectiveP1) add_affine(p Point, q AffineCached) ProjectiveP1 { ypx.add(p.y, p.x) ymx.subtract(p.y, p.x) - pp.multiply(&ypx, q.ypx) - mm.multiply(&ymx, q.ymx) + pp.multiply(ypx, q.ypx) + mm.multiply(ymx, q.ymx) tt2d.multiply(p.t, q.t2d) z2.add(p.z, p.z) diff --git a/vlib/crypto/ed25519/internal/edwards25519/table.v b/vlib/crypto/ed25519/internal/edwards25519/table.v index 8709b1f441667f..7131c2569de371 100644 --- a/vlib/crypto/ed25519/internal/edwards25519/table.v +++ b/vlib/crypto/ed25519/internal/edwards25519/table.v @@ -94,7 +94,7 @@ fn (mut v ProjLookupTable) select_into(mut dest ProjectiveCached, x i8) { for j := 1; j <= 8; j++ { // Set dest = j*Q if |x| = j cond := subtle.constant_time_byte_eq(xabs, u8(j)) - dest.selected(&v.points[j - 1], dest, cond) + dest.selected(v.points[j - 1], dest, cond) } // Now dest = |x|*Q, conditionally negate to get x*Q dest.cond_neg(int(xmask & 1)) diff --git a/vlib/net/tcp.c.v b/vlib/net/tcp.c.v index 5c5de46da08ee8..37bccc58e46735 100644 --- a/vlib/net/tcp.c.v +++ b/vlib/net/tcp.c.v @@ -583,7 +583,7 @@ pub fn (mut s TcpSocket) set_option_bool(opt SocketOption, value bool) ! { // return err_option_wrong_type // } x := int(value) - s.set_option(C.SOL_SOCKET, int(opt), &x)! + s.set_option(C.SOL_SOCKET, int(opt), x)! } pub fn (mut s TcpSocket) set_option_int(opt SocketOption, value int) ! { @@ -592,7 +592,7 @@ pub fn (mut s TcpSocket) set_option_int(opt SocketOption, value int) ! { pub fn (mut s TcpSocket) set_dualstack(on bool) ! { x := int(!on) - s.set_option(C.IPPROTO_IPV6, int(SocketOption.ipv6_only), &x)! + s.set_option(C.IPPROTO_IPV6, int(SocketOption.ipv6_only), x)! } fn (mut s TcpSocket) set_default_options() ! { diff --git a/vlib/net/unix/stream.c.v b/vlib/net/unix/stream.c.v index e3b4235eb6b485..c44536ad59ec67 100644 --- a/vlib/net/unix/stream.c.v +++ b/vlib/net/unix/stream.c.v @@ -425,7 +425,7 @@ pub fn (mut s StreamSocket) set_option_bool(opt net.SocketOption, value bool) ! return net.err_option_wrong_type } x := int(value) - s.set_option(C.SOL_SOCKET, int(opt), &x)! + s.set_option(C.SOL_SOCKET, int(opt), x)! } // set_option_bool sets an int option on the socket diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 44833021c59bcd..4f9326b0a1b5fb 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -2579,6 +2579,23 @@ fn gen_all_registers(mut t Table, without_numbers []string, with_numbers map[str return res } +pub fn (expr Expr) is_reference() bool { + return match expr { + PrefixExpr { + expr.op == .amp + } + UnsafeExpr { + expr.expr.is_reference() + } + ParExpr { + expr.expr.is_reference() + } + else { + false + } + } +} + // is `expr` a literal, i.e. it does not depend on any other declarations (C compile time constant) pub fn (expr Expr) is_literal() bool { return match expr { diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 7a669b161b7aba..b32628fe8aa32c 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -239,6 +239,12 @@ fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, lan return } } else { + // passing &expr where no-pointer is expected + if expected != ast.voidptr_type && !expected.is_ptr() && got.is_ptr() + && arg.expr.is_reference() { + got_typ_str, expected_typ_str := c.get_string_names_of(got, expected) + return error('cannot use `${got_typ_str}` as `${expected_typ_str}`') + } if expected.has_flag(.option) { got_is_ptr := got.is_ptr() || (arg.expr is ast.Ident && (arg.expr as ast.Ident).is_mut()) diff --git a/vlib/v/checker/tests/ref_to_non_ref_err.out b/vlib/v/checker/tests/ref_to_non_ref_err.out new file mode 100644 index 00000000000000..d1f158e4723b7a --- /dev/null +++ b/vlib/v/checker/tests/ref_to_non_ref_err.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/ref_to_non_ref_err.vv:10:17: error: cannot use `&Foo` as `Foo` in argument 1 to `.index()` + 8 | } + 9 | + 10 | dump(list.index(unsafe { &list[1] })) + | ~~~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/ref_to_non_ref_err.vv b/vlib/v/checker/tests/ref_to_non_ref_err.vv new file mode 100644 index 00000000000000..71765743c767f0 --- /dev/null +++ b/vlib/v/checker/tests/ref_to_non_ref_err.vv @@ -0,0 +1,10 @@ +struct Foo { + idx int +} + +mut list := []Foo{} +for i in 0..3 { + list << Foo { idx: i } +} + +dump(list.index(unsafe { &list[1] })) \ No newline at end of file diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index fbfaebc2419d31..a4594c959bf33d 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2732,6 +2732,8 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as } else if arg.expr is ast.None { g.expr_with_opt(arg.expr, arg_typ, expected_type) return + } else if arg.expr.is_literal() { + g.write('(voidptr)') } else { needs_closing = true if arg_typ_sym.kind in [.sum_type, .interface_] { diff --git a/vlib/v/gen/js/array.v b/vlib/v/gen/js/array.v index 8bd602e5e424c5..8f7f60d5b46808 100644 --- a/vlib/v/gen/js/array.v +++ b/vlib/v/gen/js/array.v @@ -50,7 +50,7 @@ fn (mut g JsGen) gen_array_index_method(left_type ast.Type) string { fn_builder.writeln('\treturn new int(-1);') fn_builder.writeln('}') g.definitions.writeln(fn_builder.str()) - left_sym.register_method(&ast.Fn{ + left_sym.register_method(ast.Fn{ name: 'index' params: [ast.Param{ typ: unwrap_left_type @@ -199,7 +199,7 @@ fn (mut g JsGen) gen_array_contains_method(left_type ast.Type) string { fn_builder.writeln('\treturn new bool(false);') fn_builder.writeln('}') g.definitions.writeln(fn_builder.str()) - left_sym.register_method(&ast.Fn{ + left_sym.register_method(ast.Fn{ name: 'contains' params: [ast.Param{ typ: unwrap_left_type