checker: disallow casting to bool, use `some_int != 0` instead (#6138)

pull/6170/head
Nick Treleaven 2020-08-19 13:37:55 +01:00 committed by GitHub
parent 55b025413d
commit 217f04e311
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 18 deletions

View File

@ -58,38 +58,38 @@ pub fn inode(path string) FileMode {
return FileMode{
typ: typ
owner: FilePermission{
read: bool(attr.st_mode & u32(C.S_IREAD))
write: bool(attr.st_mode & u32(C.S_IWRITE))
execute: bool(attr.st_mode & u32(C.S_IEXEC))
read: (attr.st_mode & u32(C.S_IREAD)) != 0
write: (attr.st_mode & u32(C.S_IWRITE)) != 0
execute: (attr.st_mode & u32(C.S_IEXEC)) != 0
}
group: FilePermission{
read: bool(attr.st_mode & u32(C.S_IREAD))
write: bool(attr.st_mode & u32(C.S_IWRITE))
execute: bool(attr.st_mode & u32(C.S_IEXEC))
read: (attr.st_mode & u32(C.S_IREAD)) != 0
write: (attr.st_mode & u32(C.S_IWRITE)) != 0
execute: (attr.st_mode & u32(C.S_IEXEC)) != 0
}
others: FilePermission{
read: bool(attr.st_mode & u32(C.S_IREAD))
write: bool(attr.st_mode & u32(C.S_IWRITE))
execute: bool(attr.st_mode & u32(C.S_IEXEC))
read: (attr.st_mode & u32(C.S_IREAD)) != 0
write: (attr.st_mode & u32(C.S_IWRITE)) != 0
execute: (attr.st_mode & u32(C.S_IEXEC)) != 0
}
}
} $else {
return FileMode{
typ: typ
owner: FilePermission{
read: bool(attr.st_mode & u32(C.S_IRUSR))
write: bool(attr.st_mode & u32(C.S_IWUSR))
execute: bool(attr.st_mode & u32(C.S_IXUSR))
read: (attr.st_mode & u32(C.S_IRUSR)) != 0
write: (attr.st_mode & u32(C.S_IWUSR)) != 0
execute: (attr.st_mode & u32(C.S_IXUSR)) != 0
}
group: FilePermission{
read: bool(attr.st_mode & u32(C.S_IRGRP))
write: bool(attr.st_mode & u32(C.S_IWGRP))
execute: bool(attr.st_mode & u32(C.S_IXGRP))
read: (attr.st_mode & u32(C.S_IRGRP)) != 0
write: (attr.st_mode & u32(C.S_IWGRP)) != 0
execute: (attr.st_mode & u32(C.S_IXGRP)) != 0
}
others: FilePermission{
read: bool(attr.st_mode & u32(C.S_IROTH))
write: bool(attr.st_mode & u32(C.S_IWOTH))
execute: bool(attr.st_mode & u32(C.S_IXOTH))
read: (attr.st_mode & u32(C.S_IROTH)) != 0
write: (attr.st_mode & u32(C.S_IWOTH)) != 0
execute: (attr.st_mode & u32(C.S_IXOTH)) != 0
}
}
}

View File

@ -2356,6 +2356,8 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
type_name := c.table.type_to_str(node.expr_type)
c.error('cannot cast `$type_name` to struct', node.pos)
}
} else if node.typ == table.bool_type {
c.error('cannot cast to bool - use e.g. `some_int != 0` instead', node.pos)
}
if node.has_arg {
c.expr(node.arg)

View File

@ -0,0 +1,20 @@
vlib/v/checker/tests/cast_err.v:3:11: error: cannot cast to bool - use e.g. `some_int != 0` instead
1 | fn test_bool_cast() {
2 | v := 3
3 | _ = bool(v)
| ^
4 | _ = bool(&v)
5 | _ = bool([2])
vlib/v/checker/tests/cast_err.v:4:11: error: cannot cast to bool - use e.g. `some_int != 0` instead
2 | v := 3
3 | _ = bool(v)
4 | _ = bool(&v)
| ^
5 | _ = bool([2])
6 | }
vlib/v/checker/tests/cast_err.v:5:11: error: cannot cast to bool - use e.g. `some_int != 0` instead
3 | _ = bool(v)
4 | _ = bool(&v)
5 | _ = bool([2])
| ~~~
6 | }

View File

@ -0,0 +1,6 @@
fn test_bool_cast() {
v := 3
_ = bool(v)
_ = bool(&v)
_ = bool([2])
}

View File

@ -0,0 +1,16 @@
fn test_conv_to_bool() {
v := 0
mut b := v != 0
assert !b
b = u64(&v) != 0
assert b
// check true -> 1
assert int(b) == 1
// branchless tests (can be important for manual optimization)
arr := [7,8]!!
e := arr[int(b)]
assert e == 8
b = e < 0
assert arr[int(b)] == 7
}