From 446631ceb57cc3ad2e4e02ed9f4d020a406049b8 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Mon, 15 Mar 2021 13:55:07 +0000 Subject: [PATCH] checker: fixed array cannot implicitly convert to fooptr (again) (#9302) --- vlib/builtin/builtin_nix.c.v | 4 ++-- vlib/builtin/builtin_windows.c.v | 2 +- vlib/builtin/int.v | 2 +- vlib/gg/text_rendering.v | 6 +++--- vlib/net/tcp.v | 2 +- vlib/net/tcp_read_line.v | 6 +++--- vlib/net/unix/stream_nix.v | 4 ++-- vlib/os/os_c.v | 4 ++-- vlib/os/os_windows.c.v | 7 ++++--- vlib/picohttpparser/request.v | 2 +- vlib/term/ui/input_windows.c.v | 2 +- vlib/v/checker/check_types.v | 16 ++++++---------- vlib/v/checker/tests/fixed_array_conv.out | 23 +++++++++++++++++++++++ vlib/v/checker/tests/fixed_array_conv.vv | 6 ++++++ vlib/v/tests/type_voidptr_test.v | 4 ++-- 15 files changed, 58 insertions(+), 32 deletions(-) diff --git a/vlib/builtin/builtin_nix.c.v b/vlib/builtin/builtin_nix.c.v index 78904ebc6a..faa4bc2cab 100644 --- a/vlib/builtin/builtin_nix.c.v +++ b/vlib/builtin/builtin_nix.c.v @@ -49,7 +49,7 @@ fn print_backtrace_skipping_top_frames(xskipframes int) bool { fn print_backtrace_skipping_top_frames_mac(skipframes int) bool { $if macos { buffer := [100]voidptr{} - nr_ptrs := C.backtrace(buffer, 100) + nr_ptrs := C.backtrace(&buffer[0], 100) if nr_ptrs < 2 { eprintln('C.backtrace returned less than 2 frames') return false @@ -62,7 +62,7 @@ fn print_backtrace_skipping_top_frames_mac(skipframes int) bool { fn print_backtrace_skipping_top_frames_freebsd(skipframes int) bool { $if freebsd { buffer := [100]voidptr{} - nr_ptrs := C.backtrace(buffer, 100) + nr_ptrs := C.backtrace(&buffer[0], 100) if nr_ptrs < 2 { eprintln('C.backtrace returned less than 2 frames') return false diff --git a/vlib/builtin/builtin_windows.c.v b/vlib/builtin/builtin_windows.c.v index 127fdd3f26..4a6986a796 100644 --- a/vlib/builtin/builtin_windows.c.v +++ b/vlib/builtin/builtin_windows.c.v @@ -131,7 +131,7 @@ fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool { return false } - frames := int(C.CaptureStackBackTrace(skipframes + 1, 100, backtraces, 0)) + frames := int(C.CaptureStackBackTrace(skipframes + 1, 100, &backtraces[0], 0)) if frames < 2 { eprintln('C.CaptureStackBackTrace returned less than 2 frames') return false diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 44369a8ed4..69a31d5cf7 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -283,7 +283,7 @@ fn u64_to_hex(nn u64, len byte) string { buf[i] = x n = n >> 4 } - return unsafe { tos(memdup(buf, len + 1), len) } + return unsafe { tos(memdup(&buf[0], len + 1), len) } } // u64_to_hex_no_leading_zeros converts the number `nn` to hexadecimal `string`. diff --git a/vlib/gg/text_rendering.v b/vlib/gg/text_rendering.v index 2ee791d7a3..fe58221d1f 100644 --- a/vlib/gg/text_rendering.v +++ b/vlib/gg/text_rendering.v @@ -215,7 +215,7 @@ pub fn (ctx &Context) text_width(s string) int { return 0 } mut buf := [4]f32{} - C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, buf) + C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, &buf[0]) if s.ends_with(' ') { return int((buf[2] - buf[0]) / ctx.scale) + ctx.text_width('i') // TODO fix this in fontstash? @@ -236,7 +236,7 @@ pub fn (ctx &Context) text_height(s string) int { return 0 } mut buf := [4]f32{} - C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, buf) + C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, &buf[0]) return int((buf[3] - buf[1]) / ctx.scale) } @@ -246,7 +246,7 @@ pub fn (ctx &Context) text_size(s string) (int, int) { return 0, 0 } mut buf := [4]f32{} - C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, buf) + C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, &buf[0]) return int((buf[2] - buf[0]) / ctx.scale), int((buf[3] - buf[1]) / ctx.scale) } diff --git a/vlib/net/tcp.v b/vlib/net/tcp.v index 902443af0e..0c24daa9b0 100644 --- a/vlib/net/tcp.v +++ b/vlib/net/tcp.v @@ -157,7 +157,7 @@ pub fn (c &TcpConn) peer_ip() ?string { peeraddr := C.sockaddr_in{} speeraddr := sizeof(peeraddr) socket_error(C.getpeername(c.sock.handle, unsafe { &C.sockaddr(&peeraddr) }, &speeraddr)) ? - cstr := charptr(C.inet_ntop(SocketFamily.inet, &peeraddr.sin_addr, buf, sizeof(buf))) + cstr := charptr(C.inet_ntop(SocketFamily.inet, &peeraddr.sin_addr, &buf[0], sizeof(buf))) if cstr == 0 { return error('net.peer_ip: inet_ntop failed') } diff --git a/vlib/net/tcp_read_line.v b/vlib/net/tcp_read_line.v index b44fd5f861..c76db99fd1 100644 --- a/vlib/net/tcp_read_line.v +++ b/vlib/net/tcp_read_line.v @@ -15,7 +15,7 @@ pub fn (mut con TcpConn) read_line() string { mut res := '' // The final result, including the ending \n. for { mut line := '' // The current line. Can be a partial without \n in it. - n := C.recv(con.sock.handle, buf, max_read - 1, msg_peek | msg_nosignal) + n := C.recv(con.sock.handle, &buf[0], max_read - 1, msg_peek | msg_nosignal) if n == -1 { return res } @@ -41,12 +41,12 @@ pub fn (mut con TcpConn) read_line() string { // Ensure that the block till the first \n (including it) // is removed from the socket's receive queue, so that it does // not get read again. - C.recv(con.sock.handle, buf, eol_idx + 1, msg_nosignal) + C.recv(con.sock.handle, &buf[0], eol_idx + 1, msg_nosignal) res += line break } // recv returned a buffer without \n in it . - C.recv(con.sock.handle, buf, n, msg_nosignal) + C.recv(con.sock.handle, &buf[0], n, msg_nosignal) res += line res += crlf break diff --git a/vlib/net/unix/stream_nix.v b/vlib/net/unix/stream_nix.v index 0a23ed8bca..44508b4adc 100644 --- a/vlib/net/unix/stream_nix.v +++ b/vlib/net/unix/stream_nix.v @@ -64,7 +64,7 @@ fn (mut s StreamSocket) connect(a string) ? { mut addr := C.sockaddr_un{} unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_un)) } addr.sun_family = C.AF_UNIX - unsafe { C.strncpy(addr.sun_path, a.str, max_sun_path) } + unsafe { C.strncpy(&addr.sun_path[0], a.str, max_sun_path) } size := C.SUN_LEN(&addr) sockaddr := unsafe { &C.sockaddr(&addr) } res := C.connect(s.handle, sockaddr, size) @@ -97,7 +97,7 @@ pub fn listen_stream(sock string) ?&StreamListener { mut addr := C.sockaddr_un{} unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_un)) } addr.sun_family = C.AF_UNIX - unsafe { C.strncpy(addr.sun_path, sock.str, max_sun_path) } + unsafe { C.strncpy(&addr.sun_path[0], sock.str, max_sun_path) } size := C.SUN_LEN(&addr) sockaddr := unsafe { &C.sockaddr(&addr) } net.socket_error(C.bind(s.handle, sockaddr, size)) ? diff --git a/vlib/os/os_c.v b/vlib/os/os_c.v index e7992c488d..6cba4bc738 100644 --- a/vlib/os/os_c.v +++ b/vlib/os/os_c.v @@ -163,11 +163,11 @@ pub fn cp(src string, dst string) ? { for { // FIXME: use sizeof, bug: 'os__buf' undeclared // count = C.read(fp_from, buf, sizeof(buf)) - count = C.read(fp_from, buf, 1024) + count = C.read(fp_from, &buf[0], 1024) if count == 0 { break } - if C.write(fp_to, buf, count) < 0 { + if C.write(fp_to, &buf[0], count) < 0 { return error_with_code('cp: failed to write to $dst', int(-1)) } } diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 88bbd550b7..dd801a3e9d 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -268,8 +268,8 @@ pub fn execute(cmd string) Result { } command_line := [32768]u16{} C.ExpandEnvironmentStringsW(cmd.to_wide(), voidptr(&command_line), 32768) - create_process_ok := C.CreateProcessW(0, command_line, 0, 0, C.TRUE, 0, 0, 0, voidptr(&start_info), - voidptr(&proc_info)) + create_process_ok := C.CreateProcessW(0, &command_line[0], 0, 0, C.TRUE, 0, 0, 0, + voidptr(&start_info), voidptr(&proc_info)) if !create_process_ok { error_num := int(C.GetLastError()) error_msg := get_error_msg(error_num) @@ -286,7 +286,8 @@ pub fn execute(cmd string) Result { for { mut result := false unsafe { - result = C.ReadFile(child_stdout_read, buf, 1000, voidptr(&bytes_read), 0) + result = C.ReadFile(child_stdout_read, &buf[0], 1000, voidptr(&bytes_read), + 0) read_data.write_bytes(&buf[0], int(bytes_read)) } if result == false || int(bytes_read) == 0 { diff --git a/vlib/picohttpparser/request.v b/vlib/picohttpparser/request.v index 60ba3125c1..3e94a886c8 100644 --- a/vlib/picohttpparser/request.v +++ b/vlib/picohttpparser/request.v @@ -24,7 +24,7 @@ pub fn (mut r Request) parse_request(s string, max_headers int) int { &r.method.str, &method_len, &r.path.str, &path_len, &minor_version, - r.headers, &num_headers, + &r.headers[0], &num_headers, 0 ) if pret > 0 { diff --git a/vlib/term/ui/input_windows.c.v b/vlib/term/ui/input_windows.c.v index af8aaeb04f..0a6d219406 100644 --- a/vlib/term/ui/input_windows.c.v +++ b/vlib/term/ui/input_windows.c.v @@ -132,7 +132,7 @@ fn (mut ctx Context) parse_events() { if nr_events < 1 { return } // print('$nr_events | ') - if !C.ReadConsoleInput(ctx.stdin_handle, ctx.read_buf, buf_size, &nr_events) { + if !C.ReadConsoleInput(ctx.stdin_handle, &ctx.read_buf[0], buf_size, &nr_events) { panic('could not read from stdin') } for i in 0 .. nr_events { diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 36170201d0..1ef7cd17fd 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -79,16 +79,9 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool { return true } } - // e.g. [4096]byte vs byteptr || [4096]char vs charptr - // should charptr be allowed as byteptr etc? - // TODO: clean this up (why was it removed?) - if got_sym.kind == .array_fixed { - info := got_sym.info as table.ArrayFixed - if !info.elem_type.is_ptr() && (info.elem_type.idx() == expected.idx() - || (info.elem_type.idx() in [table.byte_type_idx, table.char_type_idx] - && expected.idx() in [table.byteptr_type_idx, table.charptr_type_idx])) { - return true - } + if !got_.is_ptr() && got_sym.kind == .array_fixed && (exp_.is_pointer() || exp_.is_ptr()) { + // fixed array needs to be a struct, not a pointer + return false } if exp_sym.kind in [.voidptr, .any] || got_sym.kind in [.voidptr, .any] { return true @@ -266,6 +259,9 @@ pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool { return true } } + if expected == table.charptr_type && got == table.char_type.to_ptr() { + return true + } if !c.check_basic(got, expected) { // TODO: this should go away... return false } diff --git a/vlib/v/checker/tests/fixed_array_conv.out b/vlib/v/checker/tests/fixed_array_conv.out index c8e6684621..8358d9ac4f 100644 --- a/vlib/v/checker/tests/fixed_array_conv.out +++ b/vlib/v/checker/tests/fixed_array_conv.out @@ -11,8 +11,31 @@ vlib/v/checker/tests/fixed_array_conv.vv:5:4: error: mismatched types `&int` and 5 | ip = arr | ^ 6 | _ = &int(arr) + 7 | vlib/v/checker/tests/fixed_array_conv.vv:6:6: error: cannot cast a fixed array (use e.g. `&arr[0]` instead) 4 | mut ip := &int(0) 5 | ip = arr 6 | _ = &int(arr) | ~~~~~~~~ + 7 | + 8 | unsafe { +vlib/v/checker/tests/fixed_array_conv.vv:9:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup` + 7 | + 8 | unsafe { + 9 | _ = memdup(arr, 1) + | ~~~ + 10 | _ = tos(arr, 1) + 11 | fn (p &int){}(arr) +vlib/v/checker/tests/fixed_array_conv.vv:10:10: error: cannot use `[2]int` as `byteptr` in argument 1 to `tos` + 8 | unsafe { + 9 | _ = memdup(arr, 1) + 10 | _ = tos(arr, 1) + | ~~~ + 11 | fn (p &int){}(arr) + 12 | } +vlib/v/checker/tests/fixed_array_conv.vv:11:16: error: cannot use `[2]int` as `&int` in argument 1 to `anon` + 9 | _ = memdup(arr, 1) + 10 | _ = tos(arr, 1) + 11 | fn (p &int){}(arr) + | ~~~ + 12 | } diff --git a/vlib/v/checker/tests/fixed_array_conv.vv b/vlib/v/checker/tests/fixed_array_conv.vv index 4a1f015ec2..e789d87c1a 100644 --- a/vlib/v/checker/tests/fixed_array_conv.vv +++ b/vlib/v/checker/tests/fixed_array_conv.vv @@ -4,3 +4,9 @@ p = arr mut ip := &int(0) ip = arr _ = &int(arr) + +unsafe { + _ = memdup(arr, 1) + _ = tos(arr, 1) + fn (p &int){}(arr) +} diff --git a/vlib/v/tests/type_voidptr_test.v b/vlib/v/tests/type_voidptr_test.v index d0b95da741..265e7f647a 100644 --- a/vlib/v/tests/type_voidptr_test.v +++ b/vlib/v/tests/type_voidptr_test.v @@ -1,4 +1,3 @@ -[direct_array_access] [unsafe] fn memcpy(mut dest voidptr, src voidptr, len u32) voidptr { mut d := byteptr(dest) @@ -16,6 +15,7 @@ fn memcpy(mut dest voidptr, src voidptr, len u32) voidptr { fn test_mut_voidptr_arg() { mut a := [1, 2]! b := [3, 4]! - unsafe { memcpy(mut a, b, sizeof(int)) } + mut aptr := voidptr(&a[0]) + unsafe { memcpy(mut aptr, &b[0], sizeof(int)) } assert a == [3, 2]! }