Skip to content

Commit 1c7df29

Browse files
authored
checker: disallow voidptr cast to struct (#18845)
1 parent a43064a commit 1c7df29

File tree

7 files changed

+21
-8
lines changed

7 files changed

+21
-8
lines changed

vlib/term/ui/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn event(e &tui.Event, x voidptr) {
1919
}
2020
2121
fn frame(x voidptr) {
22-
mut app := &App(x)
22+
mut app := unsafe { &App(x) }
2323
2424
app.tui.clear()
2525
app.tui.set_bg_color(r: 63, g: 81, b: 181)

vlib/v/checker/checker.v

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,9 +2943,9 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
29432943
else {}
29442944
}
29452945
}
2946-
if from_type == ast.voidptr_type_idx && !c.inside_unsafe {
2947-
// TODO make this an error
2948-
c.warn('cannot cast voidptr to a struct outside `unsafe`', node.pos)
2946+
if from_type == ast.voidptr_type_idx && !c.inside_unsafe && !c.pref.translated
2947+
&& !c.file.is_translated {
2948+
c.error('cannot cast voidptr to a struct outside `unsafe`', node.pos)
29492949
}
29502950
if !from_type.is_int() && final_from_sym.kind != .enum_
29512951
&& !from_type.is_any_kind_of_pointer() {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/checker/tests/voidptr_cast_to_struct_err.vv:4:7: error: cannot cast `voidptr` to struct
2+
2 |
3+
3 | fn main() {
4+
4 | a := Foo(unsafe { nil })
5+
| ~~~~~~~~~~~~~~~~~~~
6+
5 | println(a)
7+
6 | }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct Foo {}
2+
3+
fn main() {
4+
a := Foo(unsafe { nil })
5+
println(a)
6+
}

vlib/v/tests/option_generic_ptr_return_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ struct ABCD {}
88
pub fn cast_object_desc[H](desc &ObjectDesc) ?H {
99
$if H is &ABCD {
1010
if desc.typ == 12 { // desc == ABCD
11-
return &ABCD(desc.ptr)
11+
return unsafe { &ABCD(desc.ptr) }
1212
}
1313
}
1414
return none

vlib/v/tests/option_ptr_cast_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub fn cast_object_desc[H](desc &ObjectDesc) ?H {
1414
return &ABCD(desc.ptr)
1515
}*/
1616
if desc.typ == 12 { // desc == ABCD
17-
return ?&ABCD(&ABCD(desc.ptr))
17+
return ?&ABCD(unsafe { &ABCD(desc.ptr) })
1818
}
1919
}
2020
return none

vlib/v/tests/pointers_multilevel_casts_test.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ fn test_struct_pointer_casts_with_field_selectors() {
4949
}
5050
dump(ss)
5151
pss := voidptr(ss)
52-
if &Struct(pss).name == 'abc' {
52+
if unsafe { &Struct(pss).name } == 'abc' {
5353
assert true
5454
}
55-
if &Struct(pss).x == 123 {
55+
if unsafe { &Struct(pss).x } == 123 {
5656
// &Struct cast and selecting .x
5757
assert true
5858
}

0 commit comments

Comments
 (0)