From cf3dd7a51ff98a01ff14637b12c5632cfb147172 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 12 May 2021 18:03:01 +0300 Subject: [PATCH] v.checker: fix `unused variable` warning on `*p = val` --- vlib/v/checker/checker.v | 43 +++++++++++++++++++++++++------------- vlib/v/tests/unsafe_test.v | 29 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 35c07cb793..b9984dfb89 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -121,21 +121,21 @@ pub fn (mut c Checker) check(ast_file &ast.File) { } pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) { - for _, obj in sc.objects { - match obj { - ast.Var { - if !c.pref.is_repl { - if !obj.is_used && obj.name[0] != `_` && !c.file.is_test { + if !c.pref.is_repl && !c.file.is_test { + for _, obj in sc.objects { + match obj { + ast.Var { + if !obj.is_used && obj.name[0] != `_` { c.warn('unused variable: `$obj.name`', obj.pos) } + if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' { + // if obj.is_mut && !obj.is_changed && !c.is_builtin { //TODO C error bad field not checked + // c.warn('`$obj.name` is declared as mutable, but it was never changed', + // obj.pos) + } } - if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' { - // if obj.is_mut && !obj.is_changed && !c.is_builtin { //TODO C error bad field not checked - // c.warn('`$obj.name` is declared as mutable, but it was never changed', - // obj.pos) - } + else {} } - else {} } } for child in sc.children { @@ -3323,9 +3323,24 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } ast.PrefixExpr { // Do now allow `*x = y` outside `unsafe` - if left.op == .mul && !c.inside_unsafe { - c.error('modifying variables via dereferencing can only be done in `unsafe` blocks', - assign_stmt.pos) + if left.op == .mul { + if !c.inside_unsafe { + c.error('modifying variables via dereferencing can only be done in `unsafe` blocks', + assign_stmt.pos) + } else { + // mark `p` in `*p = val` as used: + match mut left.right { + ast.Ident { + match mut left.right.obj { + ast.Var { + left.right.obj.is_used = true + } + else {} + } + } + else {} + } + } } if is_decl { c.error('non-name on the left side of `:=`', left.pos) diff --git a/vlib/v/tests/unsafe_test.v b/vlib/v/tests/unsafe_test.v index 3e7f705f2b..44ce679433 100644 --- a/vlib/v/tests/unsafe_test.v +++ b/vlib/v/tests/unsafe_test.v @@ -72,3 +72,32 @@ fn test_unsafe_if_stmt() { x := unsafe_if_stmt() assert x == 4 } + +const fixedbytes = [100]byte{} + +fn test_unsafe_pointers() { + fsize := fixedbytes.len + src := &fixedbytes[0] + // + b := []byte{} + eprintln('b.data before: $b.data') + eprintln('b.len before: $b.len') + eprintln('b.cap before: $b.cap') + assert b.len == 0 + unsafe { + // here b will be setup to work with the mmaped region + mut pdata := &b.data + mut plen := &b.len + mut pcap := &b.cap + // note that pdata, plen, pcap are used here: + *pdata = src + *plen = int(fsize) + *pcap = int(fsize) + } + assert b.len == 100 + assert b.cap == 100 + assert b.data == src + eprintln('b.data after: $b.data') + eprintln('b.len after: $b.len') + eprintln('b.cap after: $b.cap') +}