checker: warn when casting between reference types outside of `unsafe` (#7892)

pull/7897/head
Nick Treleaven 2021-01-05 15:02:04 +00:00 committed by GitHub
parent eaba21d81a
commit 3203a124b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 22 additions and 16 deletions

View File

@ -60,7 +60,9 @@ pub fn info() &LiveReloadInfo {
// started, and the structure LiveReloadInfo will not get updated.
// All its fields will be 0, but still safe to access.
mut x := &LiveReloadInfo{}
mut p := &u64(&C.g_live_info)
unsafe { *p = &u64(x) }
unsafe {
mut p := &u64(&C.g_live_info)
*p = &u64(x)
}
return x
}

View File

@ -6,7 +6,7 @@ module math
// with the sign bit of f and the result in the same bit position.
// f32_bits(f32_from_bits(x)) == x.
pub fn f32_bits(f f32) u32 {
p := *(&u32(&f))
p := *unsafe {&u32(&f)}
return p
}
@ -15,7 +15,7 @@ pub fn f32_bits(f f32) u32 {
// and the result in the same bit position.
// f32_from_bits(f32_bits(x)) == x.
pub fn f32_from_bits(b u32) f32 {
p := *(&f32(&b))
p := *unsafe {&f32(&b)}
return p
}
@ -23,7 +23,7 @@ pub fn f32_from_bits(b u32) f32 {
// with the sign bit of f and the result in the same bit position,
// and f64_bits(f64_from_bits(x)) == x.
pub fn f64_bits(f f64) u64 {
p := *(&u64(&f))
p := *unsafe {&u64(&f)}
return p
}
@ -32,7 +32,7 @@ pub fn f64_bits(f f64) u64 {
// and the result in the same bit position.
// f64_from_bits(f64_bits(x)) == x.
pub fn f64_from_bits(b u64) f64 {
p := *(&f64(&b))
p := *unsafe {&f64(&b)}
return p
}

View File

@ -40,7 +40,7 @@ fn new_addr(addr C.sockaddr) ?Addr {
}
mut saddr := buf.bytestr()
hport := (&C.sockaddr_in(&addr)).sin_port
hport := unsafe {&C.sockaddr_in(&addr)}.sin_port
port := C.ntohs(hport)
$if windows {

View File

@ -160,7 +160,7 @@ pub fn (c TcpConn) peer_ip() ?string {
buf := [44]byte{}
peeraddr := C.sockaddr_in{}
speeraddr := sizeof(peeraddr)
socket_error(C.getpeername(c.sock.handle, &C.sockaddr(&peeraddr), &speeraddr)) ?
socket_error(C.getpeername(c.sock.handle, unsafe {&C.sockaddr(&peeraddr)}, &speeraddr)) ?
cstr := C.inet_ntop(C.AF_INET, &peeraddr.sin_addr, buf, sizeof(buf))
if cstr == 0 {
return error('net.peer_ip: inet_ntop failed')
@ -190,7 +190,7 @@ pub fn listen_tcp(port int) ?TcpListener {
addr.sin_addr.s_addr = C.htonl(C.INADDR_ANY)
size := sizeof(C.sockaddr_in)
// cast to the correct type
sockaddr := &C.sockaddr(&addr)
sockaddr := unsafe {&C.sockaddr(&addr)}
socket_error(C.bind(s.handle, sockaddr, size)) ?
socket_error(C.listen(s.handle, 128)) ?
return TcpListener{
@ -205,7 +205,7 @@ pub fn (l TcpListener) accept() ?TcpConn {
unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_storage)) }
size := sizeof(C.sockaddr_storage)
// cast to correct type
sock_addr := &C.sockaddr(&addr)
sock_addr := unsafe {&C.sockaddr(&addr)}
mut new_handle := C.accept(l.sock.handle, sock_addr, &size)
if new_handle <= 0 {
l.wait_for_accept() ?
@ -344,7 +344,7 @@ pub fn (s TcpSocket) address() ?Addr {
mut addr := C.sockaddr_in{}
size := sizeof(C.sockaddr_in)
// cast to the correct type
sockaddr := &C.sockaddr(&addr)
sockaddr := unsafe {&C.sockaddr(&addr)}
C.getsockname(s.handle, sockaddr, &size)
return new_addr(sockaddr)
}

View File

@ -218,7 +218,7 @@ fn new_udp_socket(local_port int) ?UdpSocket {
size := sizeof(C.sockaddr_in)
// cast to the correct type
sockaddr := &C.sockaddr(&addr)
sockaddr := unsafe {&C.sockaddr(&addr)}
socket_error(C.bind(s.handle, sockaddr, size))?

View File

@ -474,7 +474,7 @@ enum CharClass_parse_state {
fn (re RE) get_char_class(pc int) string {
buf := []byte{len:(re.cc.len)}
mut buf_ptr := &byte(&buf)
mut buf_ptr := unsafe {&byte(&buf)}
mut cc_i := re.prog[pc].cc_index
mut i := 0

View File

@ -62,8 +62,8 @@ fn test_atof() {
// special cases
mut f1 := f64(0.0)
mut ptr := &u64(&f1)
ptr = &u64(&f1)
mut ptr := unsafe {&u64(&f1)}
ptr = unsafe {&u64(&f1)}
// double_plus_zero
f1=0.0

View File

@ -948,7 +948,7 @@ pub:
typ table.Type // `string` TODO rename to `type_to_cast_to`
pos token.Position
pub mut:
typname string
typname string // TypeSymbol.name
expr_type table.Type // `byteptr`
has_arg bool
in_prexpr bool // is the parent node an ast.PrefixExpr

View File

@ -3421,6 +3421,10 @@ 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() {
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)
}
if node.has_arg {
c.expr(node.arg)