checker: fix invalid cast warning for flag enums (#12848)

pull/12859/head
spaceface 2021-12-15 15:58:25 +01:00 committed by GitHub
parent 11d2b8b354
commit 65f12f3217
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 19 deletions

View File

@ -3592,24 +3592,30 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
if enum_decl := c.table.enum_decls[to_type_sym.name] {
mut in_range := false
mut enum_val := 0
if enum_decl.is_flag {
// if a flag enum has 4 variants, the maximum possible value would have all 4 flags set (0b1111)
max_val := (1 << enum_decl.fields.len) - 1
in_range = node_val >= 0 && node_val <= max_val
} else {
mut enum_val := 0
for enum_field in enum_decl.fields {
// check if the field of the enum value is an integer literal
if enum_field.expr is ast.IntegerLiteral {
enum_val = enum_field.expr.val.int()
for enum_field in enum_decl.fields {
// check if the field of the enum value is an integer literal
if enum_field.expr is ast.IntegerLiteral {
enum_val = enum_field.expr.val.int()
}
if node_val == enum_val {
in_range = true
break
}
enum_val += 1
}
if node_val == enum_val {
in_range = true
break
}
enum_val += 1
}
if !in_range {
c.warn('$node_val does not represents a value of enum $enum_typ_name',
c.warn('$node_val does not represent a value of enum $enum_typ_name',
node.pos)
}
}

View File

@ -1,6 +1,27 @@
vlib/v/checker/tests/enum_cast.vv:6:13: error: 12 does not represents a value of enum Color
4 | println(Color(0))
5 | println(Color(10))
6 | println(Color(12))
vlib/v/checker/tests/enum_cast.vv:9:13: error: 12 does not represent a value of enum Color
7 | println(Color(0))
8 | println(Color(10))
9 | println(Color(12))
| ~~~~~~~~~
7 | }
10 | println(Color(-10))
11 |
vlib/v/checker/tests/enum_cast.vv:10:13: error: -10 does not represent a value of enum Color
8 | println(Color(10))
9 | println(Color(12))
10 | println(Color(-10))
| ~~~~~~~~~~
11 |
12 | println(Permissions(0b101))
vlib/v/checker/tests/enum_cast.vv:13:13: error: 10 does not represent a value of enum Permissions
11 |
12 | println(Permissions(0b101))
13 | println(Permissions(0b1010))
| ~~~~~~~~~~~~~~~~~~~
14 | println(Permissions(-1))
15 | }
vlib/v/checker/tests/enum_cast.vv:14:13: error: -1 does not represent a value of enum Permissions
12 | println(Permissions(0b101))
13 | println(Permissions(0b1010))
14 | println(Permissions(-1))
| ~~~~~~~~~~~~~~~
15 | }

View File

@ -1,7 +1,15 @@
enum Color { red green = 10 blue }
[flag]
enum Permissions { read write execute }
fn main() {
println(Color(0))
println(Color(10))
println(Color(12))
}
println(Color(-10))
println(Permissions(0b101))
println(Permissions(0b1010))
println(Permissions(-1))
}