v.checker: fix `unused variable` warning on `*p = val`

pull/10088/head
Delyan Angelov 2021-05-12 18:03:01 +03:00
parent 8361f714dd
commit cf3dd7a51f
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 58 additions and 14 deletions

View File

@ -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)

View File

@ -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')
}