Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 4 commits into from
Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions vlib/live/common.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
8 changes: 4 additions & 4 deletions vlib/math/unsafe.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -15,15 +15,15 @@ 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
}

// f64_bits returns the IEEE 754 binary representation of f,
// 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
}

Expand All @@ -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
}

2 changes: 1 addition & 1 deletion vlib/net/address.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 4 additions & 4 deletions vlib/net/tcp.v
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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{
Expand All @@ -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() ?
Expand Down Expand Up @@ -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)
}
2 changes: 1 addition & 1 deletion vlib/net/udp.v
Original file line number Diff line number Diff line change
Expand Up @@ -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))?

Expand Down
2 changes: 1 addition & 1 deletion vlib/regex/regex.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions vlib/strconv/atof_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -3401,6 +3401,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)
Expand Down