checker: warn when casting between reference types outside of `unsafe` (#7892)
parent
eaba21d81a
commit
3203a124b2
|
@ -60,7 +60,9 @@ pub fn info() &LiveReloadInfo {
|
||||||
// started, and the structure LiveReloadInfo will not get updated.
|
// started, and the structure LiveReloadInfo will not get updated.
|
||||||
// All its fields will be 0, but still safe to access.
|
// All its fields will be 0, but still safe to access.
|
||||||
mut x := &LiveReloadInfo{}
|
mut x := &LiveReloadInfo{}
|
||||||
mut p := &u64(&C.g_live_info)
|
unsafe {
|
||||||
unsafe { *p = &u64(x) }
|
mut p := &u64(&C.g_live_info)
|
||||||
|
*p = &u64(x)
|
||||||
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ module math
|
||||||
// with the sign bit of f and the result in the same bit position.
|
// with the sign bit of f and the result in the same bit position.
|
||||||
// f32_bits(f32_from_bits(x)) == x.
|
// f32_bits(f32_from_bits(x)) == x.
|
||||||
pub fn f32_bits(f f32) u32 {
|
pub fn f32_bits(f f32) u32 {
|
||||||
p := *(&u32(&f))
|
p := *unsafe {&u32(&f)}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ pub fn f32_bits(f f32) u32 {
|
||||||
// and the result in the same bit position.
|
// and the result in the same bit position.
|
||||||
// f32_from_bits(f32_bits(x)) == x.
|
// f32_from_bits(f32_bits(x)) == x.
|
||||||
pub fn f32_from_bits(b u32) f32 {
|
pub fn f32_from_bits(b u32) f32 {
|
||||||
p := *(&f32(&b))
|
p := *unsafe {&f32(&b)}
|
||||||
return p
|
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,
|
// with the sign bit of f and the result in the same bit position,
|
||||||
// and f64_bits(f64_from_bits(x)) == x.
|
// and f64_bits(f64_from_bits(x)) == x.
|
||||||
pub fn f64_bits(f f64) u64 {
|
pub fn f64_bits(f f64) u64 {
|
||||||
p := *(&u64(&f))
|
p := *unsafe {&u64(&f)}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ pub fn f64_bits(f f64) u64 {
|
||||||
// and the result in the same bit position.
|
// and the result in the same bit position.
|
||||||
// f64_from_bits(f64_bits(x)) == x.
|
// f64_from_bits(f64_bits(x)) == x.
|
||||||
pub fn f64_from_bits(b u64) f64 {
|
pub fn f64_from_bits(b u64) f64 {
|
||||||
p := *(&f64(&b))
|
p := *unsafe {&f64(&b)}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ fn new_addr(addr C.sockaddr) ?Addr {
|
||||||
}
|
}
|
||||||
mut saddr := buf.bytestr()
|
mut saddr := buf.bytestr()
|
||||||
|
|
||||||
hport := (&C.sockaddr_in(&addr)).sin_port
|
hport := unsafe {&C.sockaddr_in(&addr)}.sin_port
|
||||||
port := C.ntohs(hport)
|
port := C.ntohs(hport)
|
||||||
|
|
||||||
$if windows {
|
$if windows {
|
||||||
|
|
|
@ -160,7 +160,7 @@ pub fn (c TcpConn) peer_ip() ?string {
|
||||||
buf := [44]byte{}
|
buf := [44]byte{}
|
||||||
peeraddr := C.sockaddr_in{}
|
peeraddr := C.sockaddr_in{}
|
||||||
speeraddr := sizeof(peeraddr)
|
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))
|
cstr := C.inet_ntop(C.AF_INET, &peeraddr.sin_addr, buf, sizeof(buf))
|
||||||
if cstr == 0 {
|
if cstr == 0 {
|
||||||
return error('net.peer_ip: inet_ntop failed')
|
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)
|
addr.sin_addr.s_addr = C.htonl(C.INADDR_ANY)
|
||||||
size := sizeof(C.sockaddr_in)
|
size := sizeof(C.sockaddr_in)
|
||||||
// cast to the correct type
|
// 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.bind(s.handle, sockaddr, size)) ?
|
||||||
socket_error(C.listen(s.handle, 128)) ?
|
socket_error(C.listen(s.handle, 128)) ?
|
||||||
return TcpListener{
|
return TcpListener{
|
||||||
|
@ -205,7 +205,7 @@ pub fn (l TcpListener) accept() ?TcpConn {
|
||||||
unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_storage)) }
|
unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_storage)) }
|
||||||
size := sizeof(C.sockaddr_storage)
|
size := sizeof(C.sockaddr_storage)
|
||||||
// cast to correct type
|
// 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)
|
mut new_handle := C.accept(l.sock.handle, sock_addr, &size)
|
||||||
if new_handle <= 0 {
|
if new_handle <= 0 {
|
||||||
l.wait_for_accept() ?
|
l.wait_for_accept() ?
|
||||||
|
@ -344,7 +344,7 @@ pub fn (s TcpSocket) address() ?Addr {
|
||||||
mut addr := C.sockaddr_in{}
|
mut addr := C.sockaddr_in{}
|
||||||
size := sizeof(C.sockaddr_in)
|
size := sizeof(C.sockaddr_in)
|
||||||
// cast to the correct type
|
// cast to the correct type
|
||||||
sockaddr := &C.sockaddr(&addr)
|
sockaddr := unsafe {&C.sockaddr(&addr)}
|
||||||
C.getsockname(s.handle, sockaddr, &size)
|
C.getsockname(s.handle, sockaddr, &size)
|
||||||
return new_addr(sockaddr)
|
return new_addr(sockaddr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,7 @@ fn new_udp_socket(local_port int) ?UdpSocket {
|
||||||
size := sizeof(C.sockaddr_in)
|
size := sizeof(C.sockaddr_in)
|
||||||
|
|
||||||
// cast to the correct type
|
// 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.bind(s.handle, sockaddr, size))?
|
||||||
|
|
||||||
|
|
|
@ -474,7 +474,7 @@ enum CharClass_parse_state {
|
||||||
|
|
||||||
fn (re RE) get_char_class(pc int) string {
|
fn (re RE) get_char_class(pc int) string {
|
||||||
buf := []byte{len:(re.cc.len)}
|
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 cc_i := re.prog[pc].cc_index
|
||||||
mut i := 0
|
mut i := 0
|
||||||
|
|
|
@ -62,8 +62,8 @@ fn test_atof() {
|
||||||
|
|
||||||
// special cases
|
// special cases
|
||||||
mut f1 := f64(0.0)
|
mut f1 := f64(0.0)
|
||||||
mut ptr := &u64(&f1)
|
mut ptr := unsafe {&u64(&f1)}
|
||||||
ptr = &u64(&f1)
|
ptr = unsafe {&u64(&f1)}
|
||||||
|
|
||||||
// double_plus_zero
|
// double_plus_zero
|
||||||
f1=0.0
|
f1=0.0
|
||||||
|
|
|
@ -948,7 +948,7 @@ pub:
|
||||||
typ table.Type // `string` TODO rename to `type_to_cast_to`
|
typ table.Type // `string` TODO rename to `type_to_cast_to`
|
||||||
pos token.Position
|
pos token.Position
|
||||||
pub mut:
|
pub mut:
|
||||||
typname string
|
typname string // TypeSymbol.name
|
||||||
expr_type table.Type // `byteptr`
|
expr_type table.Type // `byteptr`
|
||||||
has_arg bool
|
has_arg bool
|
||||||
in_prexpr bool // is the parent node an ast.PrefixExpr
|
in_prexpr bool // is the parent node an ast.PrefixExpr
|
||||||
|
|
|
@ -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
|
// variadic case can happen when arrays are converted into variadic
|
||||||
msg := if node.expr_type.has_flag(.optional) { 'an optional' } else { 'a variadic' }
|
msg := if node.expr_type.has_flag(.optional) { 'an optional' } else { 'a variadic' }
|
||||||
c.error('cannot type cast $msg', node.pos)
|
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 {
|
if node.has_arg {
|
||||||
c.expr(node.arg)
|
c.expr(node.arg)
|
||||||
|
|
Loading…
Reference in New Issue