From eeaf8d94d0f555f3859e368da618f2257bdd695b Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Fri, 17 May 2024 02:43:56 +0530 Subject: [PATCH] checker: disallow invalid ptr operations (#21515) --- vlib/v/checker/infix.v | 6 ++++++ .../tests/disallow_pointer_arithmetic_err.out | 14 ++++++++++++++ vlib/v/checker/tests/invalid_op_ptr_err.out | 14 ++++++++++++++ vlib/v/checker/tests/invalid_op_ptr_err.vv | 7 +++++++ vlib/v/checker/tests/pointer_ops.out | 14 ++++++++++++++ 5 files changed, 55 insertions(+) create mode 100644 vlib/v/checker/tests/invalid_op_ptr_err.out create mode 100644 vlib/v/checker/tests/invalid_op_ptr_err.vv diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 08d87a2dc..560f14bfa 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -331,6 +331,12 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } } + if ((unwrapped_left_type.is_ptr() && !node.left.is_auto_deref_var()) + || (unwrapped_right_type.is_ptr() && !node.right.is_auto_deref_var())) + && node.op !in [.plus, .minus] { + c.error('infix `${node.op}` is not defined for pointer values', left_right_pos) + } + if !c.pref.translated && left_sym.kind in [.array, .array_fixed, .map, .struct_] { if left_sym.has_method_with_generic_parent(node.op.str()) { if method := left_sym.find_method_with_generic_parent(node.op.str()) { diff --git a/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out b/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out index 2c2a8c0f0..2c67a2ca0 100644 --- a/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out +++ b/vlib/v/checker/tests/disallow_pointer_arithmetic_err.out @@ -25,6 +25,13 @@ vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:5:7: error: invalid oper | ~~~~~ 6 | _ := p * 2 //should be error 7 | _ := p + 5 //OK but only in unsafe block, r is *int +vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:5:7: error: infix `*` is not defined for pointer values + 3 | p := &x + 4 | _ := p + p //should be error + 5 | _ := p * p //should be error + | ~~~~~ + 6 | _ := p * 2 //should be error + 7 | _ := p + 5 //OK but only in unsafe block, r is *int vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:6:7: error: invalid operator `*` to `&int` and `int literal` 4 | _ := p + p //should be error 5 | _ := p * p //should be error @@ -32,3 +39,10 @@ vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:6:7: error: invalid oper | ~~~~~ 7 | _ := p + 5 //OK but only in unsafe block, r is *int 8 | _ := p - p //OK even in safe code, but n should be isize +vlib/v/checker/tests/disallow_pointer_arithmetic_err.vv:6:7: error: infix `*` is not defined for pointer values + 4 | _ := p + p //should be error + 5 | _ := p * p //should be error + 6 | _ := p * 2 //should be error + | ~~~~~ + 7 | _ := p + 5 //OK but only in unsafe block, r is *int + 8 | _ := p - p //OK even in safe code, but n should be isize diff --git a/vlib/v/checker/tests/invalid_op_ptr_err.out b/vlib/v/checker/tests/invalid_op_ptr_err.out new file mode 100644 index 000000000..0cf09ded3 --- /dev/null +++ b/vlib/v/checker/tests/invalid_op_ptr_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/invalid_op_ptr_err.vv:3:6: error: infix `*` is not defined for pointer values + 1 | num := 10 + 2 | p := &num + 3 | x := 5 * p + | ~~~~~ + 4 | y := 5 / p + 5 | dump(x) +vlib/v/checker/tests/invalid_op_ptr_err.vv:4:6: error: infix `/` is not defined for pointer values + 2 | p := &num + 3 | x := 5 * p + 4 | y := 5 / p + | ~~~~~ + 5 | dump(x) + 6 | dump(p) diff --git a/vlib/v/checker/tests/invalid_op_ptr_err.vv b/vlib/v/checker/tests/invalid_op_ptr_err.vv new file mode 100644 index 000000000..05b88977a --- /dev/null +++ b/vlib/v/checker/tests/invalid_op_ptr_err.vv @@ -0,0 +1,7 @@ +num := 10 +p := &num +x := 5 * p +y := 5 / p +dump(x) +dump(p) +dump(y) diff --git a/vlib/v/checker/tests/pointer_ops.out b/vlib/v/checker/tests/pointer_ops.out index 6aa773f10..5afb7cff6 100644 --- a/vlib/v/checker/tests/pointer_ops.out +++ b/vlib/v/checker/tests/pointer_ops.out @@ -54,6 +54,13 @@ vlib/v/checker/tests/pointer_ops.vv:15:3: error: invalid operator `%` to `&Foo` | ~~~~~~~ 16 | } 17 | } +vlib/v/checker/tests/pointer_ops.vv:15:3: error: infix `%` is not defined for pointer values + 13 | _ = p[3] + 14 | mut foo := &Foo{} + 15 | foo % 3 + | ~~~~~~~ + 16 | } + 17 | } vlib/v/checker/tests/pointer_ops.vv:15:3: error: mismatched types `&Foo` and `int literal` 13 | _ = p[3] 14 | mut foo := &Foo{} @@ -117,6 +124,13 @@ vlib/v/checker/tests/pointer_ops.vv:30:3: error: invalid operator `%` to `&Foo` | ~~~~~~~ 31 | } 32 | } +vlib/v/checker/tests/pointer_ops.vv:30:3: error: infix `%` is not defined for pointer values + 28 | _ = p[3] + 29 | mut foo := &Foo{} + 30 | foo % 3 + | ~~~~~~~ + 31 | } + 32 | } vlib/v/checker/tests/pointer_ops.vv:30:3: error: mismatched types `&Foo` and `int literal` 28 | _ = p[3] 29 | mut foo := &Foo{} -- 2.39.5