From 4ccf991f611b53bc23da9f078acdb9356241074a Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 17 Feb 2021 19:45:11 +0000 Subject: [PATCH] checker: warn when casting a fixed array (use `&arr[0]` instead) (#8787) --- vlib/builtin/builtin_nix.c.v | 9 +++++---- vlib/net/tcp_read_line.v | 3 +-- vlib/os/os_nix.c.v | 12 ++++++------ vlib/os/os_windows.c.v | 4 ++-- vlib/v/checker/checker.v | 2 ++ vlib/v/util/util.v | 4 ++-- vlib/x/websocket/message.v | 2 +- 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/vlib/builtin/builtin_nix.c.v b/vlib/builtin/builtin_nix.c.v index 4728ee6199..78904ebc6a 100644 --- a/vlib/builtin/builtin_nix.c.v +++ b/vlib/builtin/builtin_nix.c.v @@ -90,8 +90,8 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { C.tcc_backtrace("Backtrace") return false } - buffer := [100]byteptr{} - nr_ptrs := C.backtrace(voidptr(buffer), 100) + buffer := [100]voidptr{} + nr_ptrs := C.backtrace(&buffer[0], 100) if nr_ptrs < 2 { eprintln('C.backtrace returned less than 2 frames') return false @@ -117,8 +117,9 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { buf := [1000]byte{} mut output := '' unsafe { - for C.fgets(charptr(buf), 1000, f) != 0 { - output += tos(byteptr(buf), vstrlen(byteptr(buf))) + bp := &buf[0] + for C.fgets(charptr(bp), 1000, f) != 0 { + output += tos(bp, vstrlen(bp)) } } output = output.trim_space() + ':' diff --git a/vlib/net/tcp_read_line.v b/vlib/net/tcp_read_line.v index 38cbdeb199..b44fd5f861 100644 --- a/vlib/net/tcp_read_line.v +++ b/vlib/net/tcp_read_line.v @@ -34,8 +34,7 @@ pub fn (mut con TcpConn) read_line() string { break } } - bufbp := byteptr(buf) - line = unsafe { tos_clone(bufbp) } + line = unsafe { tos_clone(&buf[0]) } if eol_idx > 0 { // At this point, we are sure that recv returned valid data, // that contains *at least* one line. diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 7aa500b3ed..368113adc6 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -93,8 +93,8 @@ pub fn ls(path string) ?[]string { if isnil(ent) { break } - bptr := byteptr(ent.d_name) unsafe { + bptr := byteptr(&ent.d_name[0]) if bptr[0] == 0 || (bptr[0] == `.` && bptr[1] == 0) || (bptr[0] == `.` && bptr[1] == `.` && bptr[2] == 0) { continue @@ -169,8 +169,8 @@ pub fn exec(cmd string) ?Result { buf := [4096]byte{} mut res := strings.new_builder(1024) unsafe { - for C.fgets(charptr(buf), 4096, f) != 0 { - bufbp := byteptr(buf) + bufbp := &buf[0] + for C.fgets(charptr(bufbp), 4096, f) != 0 { res.write_bytes(bufbp, vstrlen(bufbp)) } } @@ -210,11 +210,11 @@ pub fn (mut c Command) read_line() string { buf := [4096]byte{} mut res := strings.new_builder(1024) unsafe { - for C.fgets(charptr(buf), 4096, c.f) != 0 { - bufbp := byteptr(buf) + bufbp := &buf[0] + for C.fgets(charptr(bufbp), 4096, c.f) != 0 { len := vstrlen(bufbp) for i in 0 .. len { - if int(bufbp[i]) == `\n` { + if bufbp[i] == `\n` { res.write_bytes(bufbp, i) return res.str() } diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index ad7d119565..31000f21a2 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -102,12 +102,12 @@ pub fn ls(path string) ?[]string { // NOTE:TODO: once we have a way to convert utf16 wide character to utf8 // we should use FindFirstFileW and FindNextFileW h_find_files := C.FindFirstFile(path_files.to_wide(), voidptr(&find_file_data)) - first_filename := unsafe { string_from_wide(&u16(find_file_data.c_file_name)) } + first_filename := unsafe { string_from_wide(&find_file_data.c_file_name[0]) } if first_filename != '.' && first_filename != '..' { dir_files << first_filename } for C.FindNextFile(h_find_files, voidptr(&find_file_data)) > 0 { - filename := unsafe { string_from_wide(&u16(find_file_data.c_file_name)) } + filename := unsafe { string_from_wide(&find_file_data.c_file_name[0]) } if filename != '.' && filename != '..' { dir_files << filename.clone() } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 02b1c99dd6..aea289f9db 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3911,6 +3911,8 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type { 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) + } else if from_type_sym.kind == .array_fixed && !node.expr_type.is_ptr() { + c.warn('cannot cast a fixed array (use e.g. `&arr[0]` instead)', node.pos) } if node.has_arg { c.expr(node.arg) diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index 9943edcf00..d9f32cbb38 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -30,7 +30,7 @@ pub fn vhash() string { mut buf := [50]byte{} buf[0] = 0 unsafe { - C.snprintf(charptr(buf), 50, '%s', C.V_COMMIT_HASH) + C.snprintf(charptr(&buf[0]), 50, '%s', C.V_COMMIT_HASH) return tos_clone(buf) } } @@ -98,7 +98,7 @@ pub fn githash(should_get_from_filesystem bool) string { mut buf := [50]byte{} buf[0] = 0 unsafe { - C.snprintf(charptr(buf), 50, '%s', C.V_CURRENT_COMMIT_HASH) + C.snprintf(charptr(&buf[0]), 50, '%s', C.V_CURRENT_COMMIT_HASH) return tos_clone(buf) } } diff --git a/vlib/x/websocket/message.v b/vlib/x/websocket/message.v index 469f2c2b64..ec843e635f 100644 --- a/vlib/x/websocket/message.v +++ b/vlib/x/websocket/message.v @@ -215,7 +215,7 @@ pub fn (mut ws Client) parse_frame_header() ?Frame { mut rbuff := [1]byte{} mut mask_end_byte := 0 for ws.state == .open { - read_bytes := ws.socket_read_ptr(byteptr(rbuff), 1) ? + read_bytes := ws.socket_read_ptr(&rbuff[0], 1) ? if read_bytes == 0 { // this is probably a timeout or close continue