mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check unsafe map index operation (#17000)
This commit is contained in:
parent
6bf6a40e0c
commit
21807f94a2
@ -109,9 +109,11 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
if left in [ast.Ident, ast.SelectorExpr] {
|
||||
c.prevent_sum_type_unwrapping_once = true
|
||||
}
|
||||
c.inside_left_assign = true
|
||||
if left is ast.IndexExpr {
|
||||
c.is_index_assign = true
|
||||
}
|
||||
left_type = c.expr(left)
|
||||
c.inside_left_assign = false
|
||||
c.is_index_assign = false
|
||||
c.expected_type = c.unwrap_generic(left_type)
|
||||
}
|
||||
if node.right_types.len < node.left.len { // first type or multi return types added above
|
||||
|
@ -111,7 +111,7 @@ mut:
|
||||
inside_println_arg bool
|
||||
inside_decl_rhs bool
|
||||
inside_if_guard bool // true inside the guard condition of `if x := opt() {}`
|
||||
inside_left_assign bool
|
||||
is_index_assign bool
|
||||
comptime_call_pos int // needed for correctly checking use before decl for templates
|
||||
goto_labels map[string]ast.GotoLabel // to check for unused goto labels
|
||||
}
|
||||
@ -3816,7 +3816,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||
node.pos)
|
||||
}
|
||||
|
||||
if !c.inside_unsafe && !c.is_builtin_mod && !c.inside_if_guard && !c.inside_left_assign
|
||||
if !c.inside_unsafe && !c.is_builtin_mod && !c.inside_if_guard && !c.is_index_assign
|
||||
&& typ_sym.kind == .map && node.or_expr.stmts.len == 0 {
|
||||
elem_type := c.table.value_type(typ)
|
||||
if elem_type.is_real_pointer() {
|
||||
|
14
vlib/v/checker/tests/map_index_reference_value.out
Normal file
14
vlib/v/checker/tests/map_index_reference_value.out
Normal file
@ -0,0 +1,14 @@
|
||||
vlib/v/checker/tests/map_index_reference_value.vv:7:3: notice: accessing a pointer map value requires an `or{}` block outside `unsafe`
|
||||
5 | fn main() {
|
||||
6 | mut m := map[string]&Foo{}
|
||||
7 | m['bar'].bar = 'bar'
|
||||
| ~~~~~~~
|
||||
8 | // m['bar'] << 'baz' // etc
|
||||
9 | }
|
||||
vlib/v/checker/tests/map_index_reference_value.vv:7:11: error: field `bar` of struct `&Foo` is immutable
|
||||
5 | fn main() {
|
||||
6 | mut m := map[string]&Foo{}
|
||||
7 | m['bar'].bar = 'bar'
|
||||
| ~~~
|
||||
8 | // m['bar'] << 'baz' // etc
|
||||
9 | }
|
9
vlib/v/checker/tests/map_index_reference_value.vv
Normal file
9
vlib/v/checker/tests/map_index_reference_value.vv
Normal file
@ -0,0 +1,9 @@
|
||||
struct Foo {
|
||||
bar string
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut m := map[string]&Foo{}
|
||||
m['bar'].bar = 'bar'
|
||||
// m['bar'] << 'baz' // etc
|
||||
}
|
Loading…
Reference in New Issue
Block a user