From 17b2045aa5ab1615694133dbc0fc8a6a97093eb1 Mon Sep 17 00:00:00 2001 From: shove70 Date: Fri, 10 Nov 2023 22:25:24 +0800 Subject: [PATCH] checker: fix: missing check when assignment statement lvalue is ParExpr(fix #19819) --- vlib/v/checker/assign.v | 3 +++ vlib/v/checker/tests/invalid_literal_assign_err.out | 4 ++-- vlib/v/checker/tests/prefix_expr_decl_assign_err.out | 10 ++++++++-- vlib/v/checker/tests/unsafe_deref_assign_err.out | 11 +++++++++++ vlib/v/checker/tests/unsafe_deref_assign_err.vv | 5 +++++ vlib/v/tests/assign_bitops_with_type_aliases_test.v | 6 ++++-- vlib/v/tests/mut_test.v | 4 +++- 7 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 vlib/v/checker/tests/unsafe_deref_assign_err.out create mode 100644 vlib/v/checker/tests/unsafe_deref_assign_err.vv diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index c58853a5b565a6..f0771363070e57 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -266,6 +266,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { } } node.left_types << left_type + for left is ast.ParExpr { + left = (left as ast.ParExpr).expr + } match mut left { ast.Ident { if (is_decl || left.kind == .blank_ident) && left_type.is_ptr() diff --git a/vlib/v/checker/tests/invalid_literal_assign_err.out b/vlib/v/checker/tests/invalid_literal_assign_err.out index 9d3075f2a4bda0..1c87f47c6bb1fc 100644 --- a/vlib/v/checker/tests/invalid_literal_assign_err.out +++ b/vlib/v/checker/tests/invalid_literal_assign_err.out @@ -54,9 +54,9 @@ vlib/v/checker/tests/invalid_literal_assign_err.vv:11:2: error: non-name literal | ~~~~~ 12 | (3 + 3.5) = 4 + 6.4 13 | } -vlib/v/checker/tests/invalid_literal_assign_err.vv:12:2: error: non-name literal value `(3 + 3.5)` on left side of `=` +vlib/v/checker/tests/invalid_literal_assign_err.vv:12:3: error: non-name literal value `3 + 3.5` on left side of `=` 10 | true = false 11 | 3 + 5 = 3 & 4 12 | (3 + 3.5) = 4 + 6.4 - | ~~~~~~~~~ + | ~~~~~~~ 13 | } diff --git a/vlib/v/checker/tests/prefix_expr_decl_assign_err.out b/vlib/v/checker/tests/prefix_expr_decl_assign_err.out index fdbb4cf9e128c3..1842eb032404ab 100644 --- a/vlib/v/checker/tests/prefix_expr_decl_assign_err.out +++ b/vlib/v/checker/tests/prefix_expr_decl_assign_err.out @@ -10,9 +10,15 @@ vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:2:5: error: non-name on the | ^ 3 | (*d) := 14 4 | } -vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:3:5: error: non-name `(*d)` on left side of `:=` +vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:3:10: error: modifying variables via dereferencing can only be done in `unsafe` blocks 1 | fn main() { 2 | &a := 12 3 | (*d) := 14 - | ~~~~ + | ~~ + 4 | } +vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:3:6: error: non-name on the left side of `:=` + 1 | fn main() { + 2 | &a := 12 + 3 | (*d) := 14 + | ^ 4 | } diff --git a/vlib/v/checker/tests/unsafe_deref_assign_err.out b/vlib/v/checker/tests/unsafe_deref_assign_err.out new file mode 100644 index 00000000000000..ad57f644fa2408 --- /dev/null +++ b/vlib/v/checker/tests/unsafe_deref_assign_err.out @@ -0,0 +1,11 @@ +vlib/v/checker/tests/unsafe_deref_assign_err.vv:4:7: error: modifying variables via dereferencing can only be done in `unsafe` blocks + 2 | cref := &c + 3 | + 4 | *cref = 1 + | ^ + 5 | (*cref) = 1 +vlib/v/checker/tests/unsafe_deref_assign_err.vv:5:9: error: modifying variables via dereferencing can only be done in `unsafe` blocks + 3 | + 4 | *cref = 1 + 5 | (*cref) = 1 + | ^ diff --git a/vlib/v/checker/tests/unsafe_deref_assign_err.vv b/vlib/v/checker/tests/unsafe_deref_assign_err.vv new file mode 100644 index 00000000000000..7b362287e4a4a4 --- /dev/null +++ b/vlib/v/checker/tests/unsafe_deref_assign_err.vv @@ -0,0 +1,5 @@ +c := 0 +cref := &c + +*cref = 1 +(*cref) = 1 diff --git a/vlib/v/tests/assign_bitops_with_type_aliases_test.v b/vlib/v/tests/assign_bitops_with_type_aliases_test.v index aa60fed59d1c22..9f8e60e3670a4a 100644 --- a/vlib/v/tests/assign_bitops_with_type_aliases_test.v +++ b/vlib/v/tests/assign_bitops_with_type_aliases_test.v @@ -7,8 +7,10 @@ const ( type SteamId = u64 fn (mut s SteamId) set_id(i u32) { - (*s) &= ~steamid_id_mask - (*s) |= ((u64(i) << steamid_id_shift) & steamid_id_mask) + unsafe { + (*s) &= ~steamid_id_mask + (*s) |= ((u64(i) << steamid_id_shift) & steamid_id_mask) + } } fn test_bitops_work_with_type_aliases() { diff --git a/vlib/v/tests/mut_test.v b/vlib/v/tests/mut_test.v index e5063f077c67ca..d7a8d4642ffc0d 100644 --- a/vlib/v/tests/mut_test.v +++ b/vlib/v/tests/mut_test.v @@ -25,7 +25,9 @@ fn test_mut() { n := 1 mut b := (&n) // - (*b) = 10 + unsafe { + (*b) = 10 + } // mut b := mut a // b = 10 }