checker: warn when casting number or a voidptr to reference type outside unsafe (#7900)

pull/7902/head
Nick Treleaven 2021-01-05 18:07:45 +00:00 committed by GitHub
parent 3e04dfc79f
commit 8fc33bc27d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 27 deletions

View File

@ -230,44 +230,44 @@ pub mut:
}
fn map_hash_string(pkey voidptr) u64 {
key := *&string(pkey)
key := *unsafe { &string(pkey) }
return hash.wyhash_c(key.str, u64(key.len), 0)
}
fn map_hash_int_1(pkey voidptr) u64 {
return hash.wyhash64_c(*&byte(pkey), 0)
return hash.wyhash64_c(*unsafe { &byte(pkey) }, 0)
}
fn map_hash_int_2(pkey voidptr) u64 {
return hash.wyhash64_c(*&u16(pkey), 0)
return hash.wyhash64_c(*unsafe { &u16(pkey) }, 0)
}
fn map_hash_int_4(pkey voidptr) u64 {
return hash.wyhash64_c(*&u32(pkey), 0)
return hash.wyhash64_c(*unsafe { &u32(pkey) }, 0)
}
fn map_hash_int_8(pkey voidptr) u64 {
return hash.wyhash64_c(*&u64(pkey), 0)
return hash.wyhash64_c(*unsafe { &u64(pkey) }, 0)
}
fn map_eq_string(a voidptr, b voidptr) bool {
return fast_string_eq(*&string(a), *&string(b))
return fast_string_eq(*unsafe { &string(a) }, *unsafe { &string(b) })
}
fn map_eq_int_1(a voidptr, b voidptr) bool {
return *&byte(a) == *&byte(b)
return unsafe { *&byte(a) == *&byte(b) }
}
fn map_eq_int_2(a voidptr, b voidptr) bool {
return *&u16(a) == *&u16(b)
return unsafe { *&u16(a) == *&u16(b) }
}
fn map_eq_int_4(a voidptr, b voidptr) bool {
return *&u32(a) == *&u32(b)
return unsafe { *&u32(a) == *&u32(b) }
}
fn map_eq_int_8(a voidptr, b voidptr) bool {
return *&u64(a) == *&u64(b)
return unsafe { *&u64(a) == *&u64(b) }
}
fn map_clone_string(dest voidptr, pkey voidptr) {
@ -302,7 +302,7 @@ fn map_clone_int_8(dest voidptr, pkey voidptr) {
}
fn map_free_string(pkey voidptr) {
(*&string(pkey)).free()
(*unsafe { &string(pkey) }).free()
}
fn map_free_nop(_ voidptr) {

View File

@ -91,7 +91,7 @@ pub:
}
fn gg_init_sokol_window(user_data voidptr) {
mut g := &Context(user_data)
mut g := unsafe { &Context(user_data) }
desc := sapp.create_desc()
/*
desc := C.sg_desc{
@ -159,7 +159,7 @@ fn gg_init_sokol_window(user_data voidptr) {
}
fn gg_frame_fn(user_data voidptr) {
mut ctx := &Context(user_data)
mut ctx := unsafe { &Context(user_data) }
if ctx.config.frame_fn == voidptr(0) {
return
}
@ -180,8 +180,8 @@ pub fn (mut ctx Context) refresh_ui() {
}
fn gg_event_fn(ce &C.sapp_event, user_data voidptr) {
e := &sapp.Event(ce)
mut g := &Context(user_data)
e := unsafe { &sapp.Event(ce) }
mut g := unsafe { &Context(user_data) }
if g.config.event_fn != voidptr(0) {
g.config.event_fn(e, g.config.user_data)
}
@ -215,14 +215,14 @@ fn gg_event_fn(ce &C.sapp_event, user_data voidptr) {
}
fn gg_cleanup_fn(user_data voidptr) {
mut g := &Context(user_data)
mut g := unsafe { &Context(user_data) }
if g.config.cleanup_fn != voidptr(0) {
g.config.cleanup_fn(g.config.user_data)
}
}
fn gg_fail_fn(msg charptr, user_data voidptr) {
mut g := &Context(user_data)
mut g := unsafe { &Context(user_data) }
vmsg := tos3(msg)
if g.config.fail_fn != voidptr(0) {
g.config.fail_fn(vmsg, g.config.user_data)

View File

@ -52,7 +52,7 @@ pub mut:
// so that the user can set callbacks, read meta information, etc.
pub fn info() &LiveReloadInfo {
if C.g_live_info != 0 {
return &LiveReloadInfo(C.g_live_info)
return unsafe {&LiveReloadInfo(C.g_live_info)}
}
// When the current program is not compiled with -live, simply
// return a new empty struct LiveReloadInfo in order to prevent

View File

@ -81,7 +81,7 @@ pub fn environ() map[string]string {
}
C.FreeEnvironmentStringsW(estrings)
} $else {
e := &charptr(C.environ)
e := unsafe { &charptr(C.environ) }
for i := 0; !isnil(unsafe { e[i] }); i++ {
eline := unsafe { cstring_to_vstring(byteptr(e[i])) }
eq_index := eline.index_byte(`=`)

View File

@ -143,7 +143,7 @@ fn mysubstr(s byteptr, from int, len int) string {
}
fn rw_callback(loop &C.picoev_loop, fd int, events int, cb_arg voidptr) {
mut p := &Picoev(cb_arg)
mut p := unsafe {&Picoev(cb_arg)}
if (events & C.PICOEV_TIMEOUT) != 0 {
close_conn(loop, fd)
p.idx[fd] = 0

View File

@ -164,7 +164,7 @@ fn process_in_thread(mut pool PoolProcessor, task_id int) {
pub fn (pool &PoolProcessor) get_string_item(idx int) string {
// return *(&string(pool.items[idx]))
// TODO: the below is a hack, remove it when v2 casting works again
return *(&string( pool.items[idx] ))
return *unsafe {&string( pool.items[idx] )}
}
// get_int_item - called by the worker callback.
@ -172,7 +172,7 @@ pub fn (pool &PoolProcessor) get_string_item(idx int) string {
// TODO: remove the need for this when vfmt becomes smarter.
pub fn (pool &PoolProcessor) get_int_item(idx int) int {
item := pool.items[idx]
return *(&int(item))
return *unsafe {&int(item)}
}
// TODO: uncomment, when generics work again
@ -241,14 +241,14 @@ pub fn (mut pool PoolProcessor) work_on_items_i(items []int) {
pub fn (pool &PoolProcessor) get_results_s() []SResult {
mut res := []SResult{}
for i in 0 .. pool.results.len {
res << *(&SResult(pool.results[i]))
res << *unsafe {&SResult(pool.results[i])}
}
return res
}
pub fn (pool &PoolProcessor) get_results_i() []IResult {
mut res := []IResult{}
for i in 0 .. pool.results.len {
res << *(&IResult(pool.results[i]))
res << *unsafe {&IResult(pool.results[i])}
}
return res
}

View File

@ -3426,10 +3426,13 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type {
// variadic case can happen when arrays are converted into variadic
msg := if node.expr_type.has_flag(.optional) { 'an optional' } else { 'a variadic' }
c.error('cannot type cast $msg', node.pos)
} else if !c.inside_unsafe && node.typ.is_ptr() && node.expr_type.is_ptr() {
} else if !c.inside_unsafe && node.typ.is_ptr() &&
(node.expr_type.is_ptr() || node.expr_type == table.voidptr_type ||
(node.expr_type.is_number() && node.expr !is ast.IntegerLiteral)) {
// ignore &Type(0) for now
ft := c.table.type_to_str(node.expr_type)
tt := c.table.type_to_str(node.typ)
c.warn('casting `$ft` to `$tt` is only allowed in `unsafe` code', node.pos)
c.warn('casting a `$ft` to `$tt` is only allowed in `unsafe` code', node.pos)
}
if node.has_arg {
c.expr(node.arg)
@ -5183,7 +5186,7 @@ fn (mut c Checker) verify_all_vweb_routes() {
if m.return_type == typ_vweb_result {
is_ok, nroute_attributes, nargs := c.verify_vweb_params_for_method(m)
if !is_ok {
f := &ast.FnDecl(m.source_fn)
f := unsafe { &ast.FnDecl(m.source_fn) }
if isnil(f) {
continue
}