From b9a7de5b3a9f6b1ec4615f6ba8ce90b2033662e5 Mon Sep 17 00:00:00 2001 From: shove Date: Mon, 27 Nov 2023 13:39:49 +0800 Subject: [PATCH] checker: disallow indexing mut struct, passed as a fn parameter (#19992) --- vlib/v/checker/checker.v | 10 +++++- ...ex_sumtype_interface_struct_params_err.out | 34 +++++++++++++++++++ ...dex_sumtype_interface_struct_params_err.vv | 14 ++++++++ .../index_sumtype_or_interface_params_err.out | 13 ------- .../index_sumtype_or_interface_params_err.vv | 8 ----- 5 files changed, 57 insertions(+), 22 deletions(-) create mode 100644 vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out create mode 100644 vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv delete mode 100644 vlib/v/checker/tests/index_sumtype_or_interface_params_err.out delete mode 100644 vlib/v/checker/tests/index_sumtype_or_interface_params_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 34e439cc3..bfa27d199 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4352,18 +4352,26 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { } } - if (typ.is_ptr() && !typ.has_flag(.shared_f) && !node.left.is_auto_deref_var()) + if (typ.is_ptr() && !typ.has_flag(.shared_f) && (!node.left.is_auto_deref_var() + || (typ_sym.kind == .struct_ && typ_sym.name != 'array'))) || typ.is_pointer() { mut is_ok := false + mut is_mut_struct := false if mut node.left is ast.Ident { if mut node.left.obj is ast.Var { // `mut param []T` function parameter is_ok = node.left.obj.is_mut && node.left.obj.is_arg && !typ.deref().is_ptr() + && typ_sym.kind != .struct_ + // `mut param Struct` + is_mut_struct = node.left.obj.is_mut && node.left.obj.is_arg + && typ_sym.kind == .struct_ } } if !is_ok && node.index is ast.RangeExpr { s := c.table.type_to_str(typ) c.error('type `${s}` does not support slicing', node.pos) + } else if is_mut_struct { + c.error('type `mut ${typ_sym.name}` does not support slicing', node.pos) } else if !c.inside_unsafe && !is_ok && !c.pref.translated && !c.file.is_translated { c.warn('pointer indexing is only allowed in `unsafe` blocks', node.pos) } diff --git a/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out b/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out new file mode 100644 index 000000000..10cd637b1 --- /dev/null +++ b/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.out @@ -0,0 +1,34 @@ +vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:12:9: warning: pointer indexing is only allowed in `unsafe` blocks + 10 | + 11 | _ = st1[0] + 12 | _ = st2[0] + | ~~~ + 13 | _ = st3[0] + 14 | } +vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:8:9: error: type `Foo` does not support indexing + 6 | + 7 | fn sum_type_or_interface_as_parameters(mut foo Foo, mut bar Bar, mut st1 Struct, st2 &Struct, st3 Struct) { + 8 | _ = foo[0] + | ~~~ + 9 | _ = bar[0] + 10 | +vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:9:9: error: type `Bar` does not support indexing + 7 | fn sum_type_or_interface_as_parameters(mut foo Foo, mut bar Bar, mut st1 Struct, st2 &Struct, st3 Struct) { + 8 | _ = foo[0] + 9 | _ = bar[0] + | ~~~ + 10 | + 11 | _ = st1[0] +vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:11:9: error: type `mut Struct` does not support slicing + 9 | _ = bar[0] + 10 | + 11 | _ = st1[0] + | ~~~ + 12 | _ = st2[0] + 13 | _ = st3[0] +vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv:13:9: error: type `Struct` does not support indexing + 11 | _ = st1[0] + 12 | _ = st2[0] + 13 | _ = st3[0] + | ~~~ + 14 | } diff --git a/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv b/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv new file mode 100644 index 000000000..5ea1070a3 --- /dev/null +++ b/vlib/v/checker/tests/index_sumtype_interface_struct_params_err.vv @@ -0,0 +1,14 @@ +type Foo = int | map[int]int + +interface Bar {} + +struct Struct {} + +fn sum_type_or_interface_as_parameters(mut foo Foo, mut bar Bar, mut st1 Struct, st2 &Struct, st3 Struct) { + _ = foo[0] + _ = bar[0] + + _ = st1[0] + _ = st2[0] + _ = st3[0] +} diff --git a/vlib/v/checker/tests/index_sumtype_or_interface_params_err.out b/vlib/v/checker/tests/index_sumtype_or_interface_params_err.out deleted file mode 100644 index 714ffc811..000000000 --- a/vlib/v/checker/tests/index_sumtype_or_interface_params_err.out +++ /dev/null @@ -1,13 +0,0 @@ -vlib/v/checker/tests/index_sumtype_or_interface_params_err.vv:6:9: error: type `Foo` does not support indexing - 4 | - 5 | fn sum_type_or_interface_as_parameters(mut foo Foo, mut bar Bar) { - 6 | _ = foo[0] - | ~~~ - 7 | _ = bar[0] - 8 | } -vlib/v/checker/tests/index_sumtype_or_interface_params_err.vv:7:9: error: type `Bar` does not support indexing - 5 | fn sum_type_or_interface_as_parameters(mut foo Foo, mut bar Bar) { - 6 | _ = foo[0] - 7 | _ = bar[0] - | ~~~ - 8 | } diff --git a/vlib/v/checker/tests/index_sumtype_or_interface_params_err.vv b/vlib/v/checker/tests/index_sumtype_or_interface_params_err.vv deleted file mode 100644 index c686b777b..000000000 --- a/vlib/v/checker/tests/index_sumtype_or_interface_params_err.vv +++ /dev/null @@ -1,8 +0,0 @@ -type Foo = int | map[int]int - -interface Bar {} - -fn sum_type_or_interface_as_parameters(mut foo Foo, mut bar Bar) { - _ = foo[0] - _ = bar[0] -} -- 2.39.5