From d912268e5dc45d38f4873ebcbed18e276746b23b Mon Sep 17 00:00:00 2001 From: Pierre Curto Date: Sat, 20 Jan 2024 06:25:22 +0100 Subject: [PATCH] checker: fix non dereferenced enum in match statements (fixes #10045) (#20591) --- vlib/v/checker/match.v | 8 ++++++++ vlib/v/checker/tests/match_enum_ref.out | 7 +++++++ vlib/v/checker/tests/match_enum_ref.vv | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 vlib/v/checker/tests/match_enum_ref.out create mode 100644 vlib/v/checker/tests/match_enum_ref.vv diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 44172fb94f..d74c20130c 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -300,6 +300,7 @@ fn (mut c Checker) get_comptime_number_value(mut expr ast.Expr) ?i64 { fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSymbol) { c.expected_type = node.expected_type cond_sym := c.table.sym(node.cond_type) + mut enum_ref_checked := false // branch_exprs is a histogram of how many times // an expr was used in the match mut branch_exprs := map[string]int{} @@ -385,6 +386,13 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym } ast.EnumVal { key = expr.val + if !enum_ref_checked { + enum_ref_checked = true + if node.cond_type.is_ptr() { + c.error('missing `*` dereferencing `${node.cond}` in match statement', + node.cond.pos()) + } + } } else { key = (*expr).str() diff --git a/vlib/v/checker/tests/match_enum_ref.out b/vlib/v/checker/tests/match_enum_ref.out new file mode 100644 index 0000000000..aa643fa1f2 --- /dev/null +++ b/vlib/v/checker/tests/match_enum_ref.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/match_enum_ref.vv:6:3: error: missing `*` dereferencing `t` in match statement + 4 | fn f(t &SomeType) ?int { + 5 | return match + 6 | t // note the missing asterisk + | ^ + 7 | { + 8 | .a { \ No newline at end of file diff --git a/vlib/v/checker/tests/match_enum_ref.vv b/vlib/v/checker/tests/match_enum_ref.vv new file mode 100644 index 0000000000..7d8327f3b1 --- /dev/null +++ b/vlib/v/checker/tests/match_enum_ref.vv @@ -0,0 +1,18 @@ +enum SomeType { + a +} +fn f(t &SomeType) ?int { + return match + t // note the missing asterisk + { + .a { + panic('This does not happen!') + 3 + } + } +} +fn main() { + t := SomeType.a + f(&t)? + assert false // should not happen, but does +} \ No newline at end of file