1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: disallow voidptr cast to struct (#18845)

This commit is contained in:
Swastik Baranwal 2023-07-12 13:37:34 +05:30 committed by GitHub
parent a43064af07
commit 1c7df29bed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 21 additions and 8 deletions

View File

@ -19,7 +19,7 @@ fn event(e &tui.Event, x voidptr) {
}
fn frame(x voidptr) {
mut app := &App(x)
mut app := unsafe { &App(x) }
app.tui.clear()
app.tui.set_bg_color(r: 63, g: 81, b: 181)

View File

@ -2943,9 +2943,9 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
else {}
}
}
if from_type == ast.voidptr_type_idx && !c.inside_unsafe {
// TODO make this an error
c.warn('cannot cast voidptr to a struct outside `unsafe`', node.pos)
if from_type == ast.voidptr_type_idx && !c.inside_unsafe && !c.pref.translated
&& !c.file.is_translated {
c.error('cannot cast voidptr to a struct outside `unsafe`', node.pos)
}
if !from_type.is_int() && final_from_sym.kind != .enum_
&& !from_type.is_any_kind_of_pointer() {

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/voidptr_cast_to_struct_err.vv:4:7: error: cannot cast `voidptr` to struct
2 |
3 | fn main() {
4 | a := Foo(unsafe { nil })
| ~~~~~~~~~~~~~~~~~~~
5 | println(a)
6 | }

View File

@ -0,0 +1,6 @@
struct Foo {}
fn main() {
a := Foo(unsafe { nil })
println(a)
}

View File

@ -8,7 +8,7 @@ struct ABCD {}
pub fn cast_object_desc[H](desc &ObjectDesc) ?H {
$if H is &ABCD {
if desc.typ == 12 { // desc == ABCD
return &ABCD(desc.ptr)
return unsafe { &ABCD(desc.ptr) }
}
}
return none

View File

@ -14,7 +14,7 @@ pub fn cast_object_desc[H](desc &ObjectDesc) ?H {
return &ABCD(desc.ptr)
}*/
if desc.typ == 12 { // desc == ABCD
return ?&ABCD(&ABCD(desc.ptr))
return ?&ABCD(unsafe { &ABCD(desc.ptr) })
}
}
return none

View File

@ -49,10 +49,10 @@ fn test_struct_pointer_casts_with_field_selectors() {
}
dump(ss)
pss := voidptr(ss)
if &Struct(pss).name == 'abc' {
if unsafe { &Struct(pss).name } == 'abc' {
assert true
}
if &Struct(pss).x == 123 {
if unsafe { &Struct(pss).x } == 123 {
// &Struct cast and selecting .x
assert true
}