checker: fixed array cannot implicitly convert to fooptr (again) (#9302)

pull/9321/head
Nick Treleaven 2021-03-15 13:55:07 +00:00 committed by GitHub
parent 9d168895ed
commit 446631ceb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 58 additions and 32 deletions

View File

@ -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

View File

@ -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

View File

@ -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`.

View File

@ -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)
}

View File

@ -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')
}

View File

@ -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

View File

@ -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)) ?

View File

@ -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))
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

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

View File

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

View File

@ -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)
}

View File

@ -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]!
}