diff --git a/src/codegen.cpp b/src/codegen.cpp index 40f71e38fe..096552037d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1645,7 +1645,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z zig_unreachable(); } - if (actual_bits >= wanted_bits && actual_type->id == ZigTypeIdInt && + if (actual_type->id == ZigTypeIdInt && !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed && want_runtime_safety) { diff --git a/std/os/linux/index.zig b/std/os/linux/index.zig index bfa046ba0f..ec90755164 100644 --- a/std/os/linux/index.zig +++ b/std/os/linux/index.zig @@ -703,7 +703,7 @@ pub fn dup2(old: i32, new: i32) usize { } pub fn dup3(old: i32, new: i32, flags: u32) usize { - return syscall3(SYS_dup3, @intCast(usize, old), @intCast(usize, new), flags); + return syscall3(SYS_dup3, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)), flags); } // TODO https://github.com/ziglang/zig/issues/265 @@ -747,7 +747,7 @@ pub fn getcwd(buf: [*]u8, size: usize) usize { } pub fn getdents64(fd: i32, dirp: [*]u8, count: usize) usize { - return syscall3(SYS_getdents64, @intCast(usize, fd), @ptrToInt(dirp), count); + return syscall3(SYS_getdents64, @bitCast(usize, isize(fd)), @ptrToInt(dirp), count); } pub fn inotify_init1(flags: u32) usize { @@ -755,16 +755,16 @@ pub fn inotify_init1(flags: u32) usize { } pub fn inotify_add_watch(fd: i32, pathname: [*]const u8, mask: u32) usize { - return syscall3(SYS_inotify_add_watch, @intCast(usize, fd), @ptrToInt(pathname), mask); + return syscall3(SYS_inotify_add_watch, @bitCast(usize, isize(fd)), @ptrToInt(pathname), mask); } pub fn inotify_rm_watch(fd: i32, wd: i32) usize { - return syscall2(SYS_inotify_rm_watch, @intCast(usize, fd), @intCast(usize, wd)); + return syscall2(SYS_inotify_rm_watch, @bitCast(usize, isize(fd)), @bitCast(usize, isize(wd))); } pub fn isatty(fd: i32) bool { var wsz: winsize = undefined; - return syscall3(SYS_ioctl, @intCast(usize, fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; + return syscall3(SYS_ioctl, @bitCast(usize, isize(fd)), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; } // TODO https://github.com/ziglang/zig/issues/265 @@ -774,7 +774,7 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz // TODO https://github.com/ziglang/zig/issues/265 pub fn readlinkat(dirfd: i32, noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize { - return syscall4(SYS_readlinkat, @intCast(usize, dirfd), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len); + return syscall4(SYS_readlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len); } // TODO https://github.com/ziglang/zig/issues/265 @@ -784,7 +784,7 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn mkdirat(dirfd: i32, path: [*]const u8, mode: u32) usize { - return syscall3(SYS_mkdirat, @intCast(usize, dirfd), @ptrToInt(path), mode); + return syscall3(SYS_mkdirat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode); } // TODO https://github.com/ziglang/zig/issues/265 @@ -803,7 +803,7 @@ pub fn umount2(special: [*]const u8, flags: u32) usize { } pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize { - return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @intCast(usize, fd), @bitCast(usize, offset)); + return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @bitCast(usize, isize(fd)), @bitCast(usize, offset)); } pub fn munmap(address: usize, length: usize) usize { @@ -811,23 +811,23 @@ pub fn munmap(address: usize, length: usize) usize { } pub fn read(fd: i32, buf: [*]u8, count: usize) usize { - return syscall3(SYS_read, @intCast(usize, fd), @ptrToInt(buf), count); + return syscall3(SYS_read, @bitCast(usize, isize(fd)), @ptrToInt(buf), count); } pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize { - return syscall4(SYS_preadv, @intCast(usize, fd), @ptrToInt(iov), count, offset); + return syscall4(SYS_preadv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset); } pub fn readv(fd: i32, iov: [*]const iovec, count: usize) usize { - return syscall3(SYS_readv, @intCast(usize, fd), @ptrToInt(iov), count); + return syscall3(SYS_readv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count); } pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize { - return syscall3(SYS_writev, @intCast(usize, fd), @ptrToInt(iov), count); + return syscall3(SYS_writev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count); } pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize { - return syscall4(SYS_pwritev, @intCast(usize, fd), @ptrToInt(iov), count, offset); + return syscall4(SYS_pwritev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count, offset); } // TODO https://github.com/ziglang/zig/issues/265 @@ -842,12 +842,12 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn symlinkat(existing: [*]const u8, newfd: i32, newpath: [*]const u8) usize { - return syscall3(SYS_symlinkat, @ptrToInt(existing), @intCast(usize, newfd), @ptrToInt(newpath)); + return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(newfd)), @ptrToInt(newpath)); } // TODO https://github.com/ziglang/zig/issues/265 pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { - return syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset); + return syscall4(SYS_pread, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset); } // TODO https://github.com/ziglang/zig/issues/265 @@ -856,7 +856,7 @@ pub fn access(path: [*]const u8, mode: u32) usize { } pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32) usize { - return syscall3(SYS_faccessat, @intCast(usize, dirfd), @ptrToInt(path), mode); + return syscall3(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode); } pub fn pipe(fd: *[2]i32) usize { @@ -868,11 +868,11 @@ pub fn pipe2(fd: *[2]i32, flags: u32) usize { } pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { - return syscall3(SYS_write, @intCast(usize, fd), @ptrToInt(buf), count); + return syscall3(SYS_write, @bitCast(usize, isize(fd)), @ptrToInt(buf), count); } pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { - return syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset); + return syscall4(SYS_pwrite, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset); } // TODO https://github.com/ziglang/zig/issues/265 @@ -882,7 +882,7 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const u8, flags: u32) usize { - return syscall5(SYS_renameat2, @intCast(usize, oldfd), @ptrToInt(oldpath), @intCast(usize, newfd), @ptrToInt(newpath), flags); + return syscall5(SYS_renameat2, @bitCast(usize, isize(oldfd)), @ptrToInt(oldpath), @bitCast(usize, isize(newfd)), @ptrToInt(newpath), flags); } // TODO https://github.com/ziglang/zig/issues/265 @@ -897,7 +897,8 @@ pub fn create(path: [*]const u8, perm: usize) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn openat(dirfd: i32, path: [*]const u8, flags: u32, mode: usize) usize { - return syscall4(SYS_openat, @intCast(usize, dirfd), @ptrToInt(path), flags, mode); + // dirfd could be negative, for example AT_FDCWD is -100 + return syscall4(SYS_openat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags, mode); } /// See also `clone` (from the arch-specific include) @@ -911,11 +912,11 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize { } pub fn close(fd: i32) usize { - return syscall1(SYS_close, @intCast(usize, fd)); + return syscall1(SYS_close, @bitCast(usize, isize(fd))); } pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize { - return syscall3(SYS_lseek, @intCast(usize, fd), @bitCast(usize, offset), ref_pos); + return syscall3(SYS_lseek, @bitCast(usize, isize(fd)), @bitCast(usize, offset), ref_pos); } pub fn exit(status: i32) noreturn { @@ -933,7 +934,7 @@ pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize { } pub fn kill(pid: i32, sig: i32) usize { - return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @intCast(usize, sig)); + return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @bitCast(usize, isize(sig))); } // TODO https://github.com/ziglang/zig/issues/265 @@ -943,7 +944,7 @@ pub fn unlink(path: [*]const u8) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize { - return syscall3(SYS_unlinkat, @intCast(usize, dirfd), @ptrToInt(path), flags); + return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags); } pub fn waitpid(pid: i32, status: *i32, options: i32) usize { @@ -1120,8 +1121,8 @@ pub const empty_sigset = []usize{0} ** sigset_t.len; pub fn raise(sig: i32) usize { var set: sigset_t = undefined; blockAppSignals(&set); - const tid = @intCast(i32, syscall0(SYS_gettid)); - const ret = syscall2(SYS_tkill, @intCast(usize, tid), @intCast(usize, sig)); + const tid = syscall0(SYS_gettid); + const ret = syscall2(SYS_tkill, tid, @bitCast(usize, isize(sig))); restoreSignals(&set); return ret; } @@ -1189,11 +1190,11 @@ pub const iovec_const = extern struct { }; pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { - return syscall3(SYS_getsockname, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len)); + return syscall3(SYS_getsockname, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len)); } pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { - return syscall3(SYS_getpeername, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len)); + return syscall3(SYS_getpeername, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len)); } pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { @@ -1201,47 +1202,47 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { } pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize { - return syscall5(SYS_setsockopt, @intCast(usize, fd), level, optname, @ptrToInt(optval), @intCast(usize, optlen)); + return syscall5(SYS_setsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen)); } pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize { - return syscall5(SYS_getsockopt, @intCast(usize, fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen)); + return syscall5(SYS_getsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen)); } pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize { - return syscall3(SYS_sendmsg, @intCast(usize, fd), @ptrToInt(msg), flags); + return syscall3(SYS_sendmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags); } pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize { - return syscall3(SYS_connect, @intCast(usize, fd), @ptrToInt(addr), len); + return syscall3(SYS_connect, @bitCast(usize, isize(fd)), @ptrToInt(addr), len); } pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize { - return syscall3(SYS_recvmsg, @intCast(usize, fd), @ptrToInt(msg), flags); + return syscall3(SYS_recvmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags); } pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize { - return syscall6(SYS_recvfrom, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen)); + return syscall6(SYS_recvfrom, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen)); } pub fn shutdown(fd: i32, how: i32) usize { - return syscall2(SYS_shutdown, @intCast(usize, fd), @intCast(usize, how)); + return syscall2(SYS_shutdown, @bitCast(usize, isize(fd)), @bitCast(usize, isize(how))); } pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize { - return syscall3(SYS_bind, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len)); + return syscall3(SYS_bind, @bitCast(usize, isize(fd)), @ptrToInt(addr), @intCast(usize, len)); } pub fn listen(fd: i32, backlog: u32) usize { - return syscall2(SYS_listen, @intCast(usize, fd), backlog); + return syscall2(SYS_listen, @bitCast(usize, isize(fd)), backlog); } pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize { - return syscall6(SYS_sendto, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen)); + return syscall6(SYS_sendto, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen)); } pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize { - return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(*fd[0])); + return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(&fd[0])); } pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { @@ -1249,11 +1250,11 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { } pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize { - return syscall4(SYS_accept4, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len), flags); + return syscall4(SYS_accept4, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len), flags); } pub fn fstat(fd: i32, stat_buf: *Stat) usize { - return syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf)); + return syscall2(SYS_fstat, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf)); } // TODO https://github.com/ziglang/zig/issues/265 @@ -1268,7 +1269,7 @@ pub fn lstat(pathname: [*]const u8, statbuf: *Stat) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize { - return syscall4(SYS_fstatat, @intCast(usize, dirfd), @ptrToInt(path), @ptrToInt(stat_buf), flags); + return syscall4(SYS_fstatat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags); } // TODO https://github.com/ziglang/zig/issues/265 @@ -1355,7 +1356,7 @@ pub fn epoll_create1(flags: usize) usize { } pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize { - return syscall4(SYS_epoll_ctl, @intCast(usize, epoll_fd), @intCast(usize, op), @intCast(usize, fd), @ptrToInt(ev)); + return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev)); } pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize { @@ -1363,7 +1364,15 @@ pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout } pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize { - return syscall6(SYS_epoll_pwait, @intCast(usize, epoll_fd), @ptrToInt(events), @intCast(usize, maxevents), @intCast(usize, timeout), @ptrToInt(sigmask), @sizeOf(sigset_t)); + return syscall6( + SYS_epoll_pwait, + @bitCast(usize, isize(epoll_fd)), + @ptrToInt(events), + @intCast(usize, maxevents), + @bitCast(usize, isize(timeout)), + @ptrToInt(sigmask), + @sizeOf(sigset_t), + ); } pub fn eventfd(count: u32, flags: u32) usize { @@ -1371,7 +1380,7 @@ pub fn eventfd(count: u32, flags: u32) usize { } pub fn timerfd_create(clockid: i32, flags: u32) usize { - return syscall2(SYS_timerfd_create, @intCast(usize, clockid), flags); + return syscall2(SYS_timerfd_create, @bitCast(usize, isize(clockid)), flags); } pub const itimerspec = extern struct { @@ -1380,11 +1389,11 @@ pub const itimerspec = extern struct { }; pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize { - return syscall2(SYS_timerfd_gettime, @intCast(usize, fd), @ptrToInt(curr_value)); + return syscall2(SYS_timerfd_gettime, @bitCast(usize, isize(fd)), @ptrToInt(curr_value)); } pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize { - return syscall4(SYS_timerfd_settime, @intCast(usize, fd), flags, @ptrToInt(new_value), @ptrToInt(old_value)); + return syscall4(SYS_timerfd_settime, @bitCast(usize, isize(fd)), flags, @ptrToInt(new_value), @ptrToInt(old_value)); } pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330; diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig index 343b3ff592..7c13f5b6fa 100644 --- a/test/runtime_safety.zig +++ b/test/runtime_safety.zig @@ -275,6 +275,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\} ); + cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer - widening", + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { + \\ @import("std").os.exit(126); + \\} + \\pub fn main() void { + \\ var value: c_short = -1; + \\ var casted = @intCast(u32, value); + \\} + ); + cases.addRuntimeSafety("unwrap error", \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {