checker: prevent from casting non-struct to struct (#6143)

pull/6152/head^2
Nick Treleaven 2020-08-17 10:19:44 +01:00 committed by GitHub
parent 0c7d73c8b0
commit 6ba6a22a77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 5 deletions

View File

@ -2333,11 +2333,17 @@ 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 `$type_name` to `byte`', node.pos)
} else if to_type_sym.kind == .struct_ && !node.typ.is_ptr() && !(to_type_sym.info as table.Struct).is_typedef {
from_type_info := from_type_sym.info as table.Struct
to_type_info := to_type_sym.info as table.Struct
if !c.check_struct_signature(from_type_info, to_type_info) {
c.error('cannot convert struct `$from_type_sym.name` to struct `$to_type_sym.name`',
node.pos)
// For now we ignore C typedef because of `C.Window(C.None)` in vlib/clipboard
if from_type_sym.kind == .struct_ && !node.expr_type.is_ptr() {
from_type_info := from_type_sym.info as table.Struct
to_type_info := to_type_sym.info as table.Struct
if !c.check_struct_signature(from_type_info, to_type_info) {
c.error('cannot convert struct `$from_type_sym.name` to struct `$to_type_sym.name`',
node.pos)
}
} else {
type_name := c.table.type_to_str(node.expr_type)
c.error('cannot cast `$type_name` to struct', node.pos)
}
}
if node.has_arg {

View File

@ -0,0 +1,27 @@
vlib/v/checker/tests/cannot_cast_to_struct.v:10:12: error: cannot convert struct `Abc` to struct `Test`
8 |
9 | fn main() {
10 | _ := Test(Abc{})
| ~~~~~
11 | sum := Alphabet(Xyz{})
12 | _ = Xyz(sum)
vlib/v/checker/tests/cannot_cast_to_struct.v:12:10: error: cannot cast `Alphabet` to struct
10 | _ := Test(Abc{})
11 | sum := Alphabet(Xyz{})
12 | _ = Xyz(sum)
| ~~~
13 | _ = Xyz(5)
14 | s := Abc{}
vlib/v/checker/tests/cannot_cast_to_struct.v:13:10: error: cannot cast `any_int` to struct
11 | sum := Alphabet(Xyz{})
12 | _ = Xyz(sum)
13 | _ = Xyz(5)
| ^
14 | s := Abc{}
15 | _ = Xyz(&s)
vlib/v/checker/tests/cannot_cast_to_struct.v:15:10: error: cannot cast `&Abc` to struct
13 | _ = Xyz(5)
14 | s := Abc{}
15 | _ = Xyz(&s)
| ^
16 | }

View File

@ -0,0 +1,16 @@
struct Abc {}
struct Xyz {}
type Alphabet = Abc | Xyz
struct Test {
abc Alphabet
}
fn main() {
_ := Test(Abc{})
sum := Alphabet(Xyz{})
_ = Xyz(sum)
_ = Xyz(5)
s := Abc{}
_ = Xyz(&s)
}