authorgravatar for chraghiali1@gmail.comAli Chraghi <chraghiali1@gmail.com> 2022-05-22 19:36:59+04:30
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-27 16:43:33-04:00
log0e6285c8fc31ff866df96847fe34e660da38b4a9
tree5d5830d5b3ce6c13041aacb7e073763551cb4852
parentddd5b57045d38b7d1f7d5a4120302797433233cd

math: make `cast` return optional instead of an error


37 files changed, 152 insertions(+), 175 deletions(-)

lib/std/Thread.zig+2-2
...@@ -88,7 +88,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {...@@ -88,7 +88,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
88 .windows => {88 .windows => {
89 var buf: [max_name_len]u16 = undefined;89 var buf: [max_name_len]u16 = undefined;
90 const len = try std.unicode.utf8ToUtf16Le(&buf, name);90 const len = try std.unicode.utf8ToUtf16Le(&buf, name);
91 const byte_len = math.cast(c_ushort, len * 2) catch return error.NameTooLong;91 const byte_len = math.cast(c_ushort, len * 2) orelse return error.NameTooLong;
9292
93 // Note: NT allocates its own copy, no use-after-free here.93 // Note: NT allocates its own copy, no use-after-free here.
94 const unicode_string = os.windows.UNICODE_STRING{94 const unicode_string = os.windows.UNICODE_STRING{
...@@ -526,7 +526,7 @@ const WindowsThreadImpl = struct {...@@ -526,7 +526,7 @@ const WindowsThreadImpl = struct {
526 // Windows appears to only support SYSTEM_INFO.dwAllocationGranularity minimum stack size.526 // Windows appears to only support SYSTEM_INFO.dwAllocationGranularity minimum stack size.
527 // Going lower makes it default to that specified in the executable (~1mb).527 // Going lower makes it default to that specified in the executable (~1mb).
528 // Its also fine if the limit here is incorrect as stack size is only a hint.528 // Its also fine if the limit here is incorrect as stack size is only a hint.
529 var stack_size = std.math.cast(u32, config.stack_size) catch std.math.maxInt(u32);529 var stack_size = std.math.cast(u32, config.stack_size) orelse std.math.maxInt(u32);
530 stack_size = std.math.max(64 * 1024, stack_size);530 stack_size = std.math.max(64 * 1024, stack_size);
531531
532 instance.thread.thread_handle = windows.kernel32.CreateThread(532 instance.thread.thread_handle = windows.kernel32.CreateThread(
lib/std/Thread/Condition.zig+1-1
...@@ -152,7 +152,7 @@ const WindowsImpl = struct {...@@ -152,7 +152,7 @@ const WindowsImpl = struct {
152 // Round the nanoseconds to the nearest millisecond,152 // Round the nanoseconds to the nearest millisecond,
153 // then saturating cast it to windows DWORD for use in kernel32 call.153 // then saturating cast it to windows DWORD for use in kernel32 call.
154 const ms = (timeout_ns +| (std.time.ns_per_ms / 2)) / std.time.ns_per_ms;154 const ms = (timeout_ns +| (std.time.ns_per_ms / 2)) / std.time.ns_per_ms;
155 timeout_ms = std.math.cast(os.windows.DWORD, ms) catch std.math.maxInt(os.windows.DWORD);155 timeout_ms = std.math.cast(os.windows.DWORD, ms) orelse std.math.maxInt(os.windows.DWORD);
156156
157 // Track if the timeout overflowed into INFINITE and make sure not to wait forever.157 // Track if the timeout overflowed into INFINITE and make sure not to wait forever.
158 if (timeout_ms == os.windows.INFINITE) {158 if (timeout_ms == os.windows.INFINITE) {
lib/std/Thread/Futex.zig+5-5
...@@ -193,7 +193,7 @@ const DarwinImpl = struct {...@@ -193,7 +193,7 @@ const DarwinImpl = struct {
193 break :blk os.darwin.__ulock_wait2(flags, addr, expect, timeout_ns, 0);193 break :blk os.darwin.__ulock_wait2(flags, addr, expect, timeout_ns, 0);
194 }194 }
195195
196 const timeout_us = std.math.cast(u32, timeout_ns / std.time.ns_per_us) catch overflow: {196 const timeout_us = std.math.cast(u32, timeout_ns / std.time.ns_per_us) orelse overflow: {
197 timeout_overflowed = true;197 timeout_overflowed = true;
198 break :overflow std.math.maxInt(u32);198 break :overflow std.math.maxInt(u32);
199 };199 };
...@@ -274,7 +274,7 @@ const LinuxImpl = struct {...@@ -274,7 +274,7 @@ const LinuxImpl = struct {
274 const rc = os.linux.futex_wake(274 const rc = os.linux.futex_wake(
275 @ptrCast(*const i32, &ptr.value),275 @ptrCast(*const i32, &ptr.value),
276 os.linux.FUTEX.PRIVATE_FLAG | os.linux.FUTEX.WAKE,276 os.linux.FUTEX.PRIVATE_FLAG | os.linux.FUTEX.WAKE,
277 std.math.cast(i32, max_waiters) catch std.math.maxInt(i32),277 std.math.cast(i32, max_waiters) orelse std.math.maxInt(i32),
278 );278 );
279279
280 switch (os.linux.getErrno(rc)) {280 switch (os.linux.getErrno(rc)) {
...@@ -379,7 +379,7 @@ const OpenbsdImpl = struct {...@@ -379,7 +379,7 @@ const OpenbsdImpl = struct {
379 const rc = os.openbsd.futex(379 const rc = os.openbsd.futex(
380 @ptrCast(*const volatile u32, &ptr.value),380 @ptrCast(*const volatile u32, &ptr.value),
381 os.openbsd.FUTEX_WAKE | os.openbsd.FUTEX_PRIVATE_FLAG,381 os.openbsd.FUTEX_WAKE | os.openbsd.FUTEX_PRIVATE_FLAG,
382 std.math.cast(c_int, max_waiters) catch std.math.maxInt(c_int),382 std.math.cast(c_int, max_waiters) orelse std.math.maxInt(c_int),
383 null, // FUTEX_WAKE takes no timeout ptr383 null, // FUTEX_WAKE takes no timeout ptr
384 null, // FUTEX_WAKE takes no requeue address384 null, // FUTEX_WAKE takes no requeue address
385 );385 );
...@@ -400,7 +400,7 @@ const DragonflyImpl = struct {...@@ -400,7 +400,7 @@ const DragonflyImpl = struct {
400400
401 if (timeout) |delay| {401 if (timeout) |delay| {
402 assert(delay != 0); // handled by timedWait().402 assert(delay != 0); // handled by timedWait().
403 timeout_us = std.math.cast(c_int, delay / std.time.ns_per_us) catch blk: {403 timeout_us = std.math.cast(c_int, delay / std.time.ns_per_us) orelse blk: {
404 timeout_overflowed = true;404 timeout_overflowed = true;
405 break :blk std.math.maxInt(c_int);405 break :blk std.math.maxInt(c_int);
406 };406 };
...@@ -436,7 +436,7 @@ const DragonflyImpl = struct {...@@ -436,7 +436,7 @@ const DragonflyImpl = struct {
436 fn wake(ptr: *const Atomic(u32), max_waiters: u32) void {436 fn wake(ptr: *const Atomic(u32), max_waiters: u32) void {
437 // A count of zero means wake all waiters.437 // A count of zero means wake all waiters.
438 assert(max_waiters != 0);438 assert(max_waiters != 0);
439 const to_wake = std.math.cast(c_int, max_waiters) catch 0;439 const to_wake = std.math.cast(c_int, max_waiters) orelse 0;
440440
441 // https://man.dragonflybsd.org/?command=umtx&section=2441 // https://man.dragonflybsd.org/?command=umtx&section=2
442 // > umtx_wakeup() will generally return 0 unless the address is bad.442 // > umtx_wakeup() will generally return 0 unless the address is bad.
lib/std/child_process.zig+1-1
...@@ -284,7 +284,7 @@ pub const ChildProcess = struct {...@@ -284,7 +284,7 @@ pub const ChildProcess = struct {
284 const next_buf = buf.unusedCapacitySlice();284 const next_buf = buf.unusedCapacitySlice();
285 if (next_buf.len == 0) return .full;285 if (next_buf.len == 0) return .full;
286 var read_bytes: u32 = undefined;286 var read_bytes: u32 = undefined;
287 const read_result = windows.kernel32.ReadFile(handle, next_buf.ptr, math.cast(u32, next_buf.len) catch maxInt(u32), &read_bytes, overlapped);287 const read_result = windows.kernel32.ReadFile(handle, next_buf.ptr, math.cast(u32, next_buf.len) orelse maxInt(u32), &read_bytes, overlapped);
288 if (read_result == 0) return switch (windows.kernel32.GetLastError()) {288 if (read_result == 0) return switch (windows.kernel32.GetLastError()) {
289 .IO_PENDING => .pending,289 .IO_PENDING => .pending,
290 .BROKEN_PIPE => .closed,290 .BROKEN_PIPE => .closed,
lib/std/debug.zig+6-6
...@@ -853,9 +853,9 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo...@@ -853,9 +853,9 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo
853 }853 }
854}854}
855855
856fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {856fn chopSlice(ptr: []const u8, offset: u64, size: u64) error{Overflow}![]const u8 {
857 const start = try math.cast(usize, offset);857 const start = math.cast(usize, offset) orelse return error.Overflow;
858 const end = start + try math.cast(usize, size);858 const end = start + (math.cast(usize, size) orelse return error.Overflow);
859 return ptr[start..end];859 return ptr[start..end];
860}860}
861861
...@@ -880,7 +880,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn...@@ -880,7 +880,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn
880 const str_section_off = shoff + @as(u64, hdr.e_shentsize) * @as(u64, hdr.e_shstrndx);880 const str_section_off = shoff + @as(u64, hdr.e_shentsize) * @as(u64, hdr.e_shstrndx);
881 const str_shdr = @ptrCast(881 const str_shdr = @ptrCast(
882 *const elf.Shdr,882 *const elf.Shdr,
883 @alignCast(@alignOf(elf.Shdr), &mapped_mem[try math.cast(usize, str_section_off)]),883 @alignCast(@alignOf(elf.Shdr), &mapped_mem[math.cast(usize, str_section_off) orelse return error.Overflow]),
884 );884 );
885 const header_strings = mapped_mem[str_shdr.sh_offset .. str_shdr.sh_offset + str_shdr.sh_size];885 const header_strings = mapped_mem[str_shdr.sh_offset .. str_shdr.sh_offset + str_shdr.sh_size];
886 const shdrs = @ptrCast(886 const shdrs = @ptrCast(
...@@ -1119,7 +1119,7 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {...@@ -1119,7 +1119,7 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
1119 nosuspend {1119 nosuspend {
1120 defer file.close();1120 defer file.close();
11211121
1122 const file_len = try math.cast(usize, try file.getEndPos());1122 const file_len = math.cast(usize, try file.getEndPos()) orelse math.maxInt(usize);
1123 const mapped_mem = try os.mmap(1123 const mapped_mem = try os.mmap(
1124 null,1124 null,
1125 file_len,1125 file_len,
...@@ -1248,7 +1248,7 @@ pub const DebugInfo = struct {...@@ -1248,7 +1248,7 @@ pub const DebugInfo = struct {
1248 if (windows.kernel32.K32EnumProcessModules(1248 if (windows.kernel32.K32EnumProcessModules(
1249 process_handle,1249 process_handle,
1250 modules.ptr,1250 modules.ptr,
1251 try math.cast(windows.DWORD, modules.len * @sizeOf(windows.HMODULE)),1251 math.cast(windows.DWORD, modules.len * @sizeOf(windows.HMODULE)) orelse return error.Overflow,
1252 &bytes_needed,1252 &bytes_needed,
1253 ) == 0)1253 ) == 0)
1254 return error.MissingDebugInfo;1254 return error.MissingDebugInfo;
lib/std/dwarf.zig+3-3
...@@ -1068,7 +1068,7 @@ pub const DwarfInfo = struct {...@@ -1068,7 +1068,7 @@ pub const DwarfInfo = struct {
1068 });1068 });
1069 },1069 },
1070 else => {1070 else => {
1071 const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo;1071 const fwd_amt = math.cast(isize, op_size - 1) orelse return error.InvalidDebugInfo;
1072 try seekable.seekBy(fwd_amt);1072 try seekable.seekBy(fwd_amt);
1073 },1073 },
1074 }1074 }
...@@ -1133,7 +1133,7 @@ pub const DwarfInfo = struct {...@@ -1133,7 +1133,7 @@ pub const DwarfInfo = struct {
1133 fn getString(di: *DwarfInfo, offset: u64) ![]const u8 {1133 fn getString(di: *DwarfInfo, offset: u64) ![]const u8 {
1134 if (offset > di.debug_str.len)1134 if (offset > di.debug_str.len)
1135 return error.InvalidDebugInfo;1135 return error.InvalidDebugInfo;
1136 const casted_offset = math.cast(usize, offset) catch1136 const casted_offset = math.cast(usize, offset) orelse
1137 return error.InvalidDebugInfo;1137 return error.InvalidDebugInfo;
11381138
1139 // Valid strings always have a terminating zero byte1139 // Valid strings always have a terminating zero byte
...@@ -1148,7 +1148,7 @@ pub const DwarfInfo = struct {...@@ -1148,7 +1148,7 @@ pub const DwarfInfo = struct {
1148 const debug_line_str = di.debug_line_str orelse return error.InvalidDebugInfo;1148 const debug_line_str = di.debug_line_str orelse return error.InvalidDebugInfo;
1149 if (offset > debug_line_str.len)1149 if (offset > debug_line_str.len)
1150 return error.InvalidDebugInfo;1150 return error.InvalidDebugInfo;
1151 const casted_offset = math.cast(usize, offset) catch1151 const casted_offset = math.cast(usize, offset) orelse
1152 return error.InvalidDebugInfo;1152 return error.InvalidDebugInfo;
11531153
1154 // Valid strings always have a terminating zero byte1154 // Valid strings always have a terminating zero byte
lib/std/dynamic_library.zig+2-1
...@@ -104,6 +104,7 @@ pub const ElfDynLib = struct {...@@ -104,6 +104,7 @@ pub const ElfDynLib = struct {
104 memory: []align(mem.page_size) u8,104 memory: []align(mem.page_size) u8,
105105
106 pub const Error = error{106 pub const Error = error{
107 FileTooBig,
107 NotElfFile,108 NotElfFile,
108 NotDynamicLibrary,109 NotDynamicLibrary,
109 MissingDynamicLinkingInformation,110 MissingDynamicLinkingInformation,
...@@ -118,7 +119,7 @@ pub const ElfDynLib = struct {...@@ -118,7 +119,7 @@ pub const ElfDynLib = struct {
118 defer os.close(fd);119 defer os.close(fd);
119120
120 const stat = try os.fstat(fd);121 const stat = try os.fstat(fd);
121 const size = try std.math.cast(usize, stat.size);122 const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig;
122123
123 // This one is to read the ELF info. We do more mmapping later124 // This one is to read the ELF info. We do more mmapping later
124 // corresponding to the actual LOAD sections.125 // corresponding to the actual LOAD sections.
lib/std/fmt.zig+3-6
...@@ -1778,8 +1778,8 @@ fn parseWithSign(...@@ -1778,8 +1778,8 @@ fn parseWithSign(
1778 if (c == '_') continue;1778 if (c == '_') continue;
1779 const digit = try charToDigit(c, buf_radix);1779 const digit = try charToDigit(c, buf_radix);
17801780
1781 if (x != 0) x = try math.mul(T, x, try math.cast(T, buf_radix));1781 if (x != 0) x = try math.mul(T, x, math.cast(T, buf_radix) orelse return error.Overflow);
1782 x = try add(T, x, try math.cast(T, digit));1782 x = try add(T, x, math.cast(T, digit) orelse return error.Overflow);
1783 }1783 }
17841784
1785 return x;1785 return x;
...@@ -1893,10 +1893,7 @@ pub fn count(comptime fmt: []const u8, args: anytype) u64 {...@@ -1893,10 +1893,7 @@ pub fn count(comptime fmt: []const u8, args: anytype) u64 {
1893pub const AllocPrintError = error{OutOfMemory};1893pub const AllocPrintError = error{OutOfMemory};
18941894
1895pub fn allocPrint(allocator: mem.Allocator, comptime fmt: []const u8, args: anytype) AllocPrintError![]u8 {1895pub fn allocPrint(allocator: mem.Allocator, comptime fmt: []const u8, args: anytype) AllocPrintError![]u8 {
1896 const size = math.cast(usize, count(fmt, args)) catch |err| switch (err) {1896 const size = math.cast(usize, count(fmt, args)) orelse return error.OutOfMemory;
1897 // Output too long. Can't possibly allocate enough memory to display it.
1898 error.Overflow => return error.OutOfMemory,
1899 };
1900 const buf = try allocator.alloc(u8, size);1897 const buf = try allocator.alloc(u8, size);
1901 return bufPrint(buf, fmt, args) catch |err| switch (err) {1898 return bufPrint(buf, fmt, args) catch |err| switch (err) {
1902 error.NoSpaceLeft => unreachable, // we just counted the size above1899 error.NoSpaceLeft => unreachable, // we just counted the size above
lib/std/fs.zig+1-1
...@@ -1899,7 +1899,7 @@ pub const Dir = struct {...@@ -1899,7 +1899,7 @@ pub const Dir = struct {
18991899
1900 // If the file size doesn't fit a usize it'll be certainly greater than1900 // If the file size doesn't fit a usize it'll be certainly greater than
1901 // `max_bytes`1901 // `max_bytes`
1902 const stat_size = size_hint orelse math.cast(usize, try file.getEndPos()) catch1902 const stat_size = size_hint orelse math.cast(usize, try file.getEndPos()) orelse
1903 return error.FileTooBig;1903 return error.FileTooBig;
19041904
1905 return file.readToEndAllocOptions(allocator, max_bytes, stat_size, alignment, optional_sentinel);1905 return file.readToEndAllocOptions(allocator, max_bytes, stat_size, alignment, optional_sentinel);
lib/std/fs/file.zig+5-5
...@@ -907,12 +907,12 @@ pub const File = struct {...@@ -907,12 +907,12 @@ pub const File = struct {
907 }907 }
908 const times = [2]os.timespec{908 const times = [2]os.timespec{
909 os.timespec{909 os.timespec{
910 .tv_sec = math.cast(isize, @divFloor(atime, std.time.ns_per_s)) catch maxInt(isize),910 .tv_sec = math.cast(isize, @divFloor(atime, std.time.ns_per_s)) orelse maxInt(isize),
911 .tv_nsec = math.cast(isize, @mod(atime, std.time.ns_per_s)) catch maxInt(isize),911 .tv_nsec = math.cast(isize, @mod(atime, std.time.ns_per_s)) orelse maxInt(isize),
912 },912 },
913 os.timespec{913 os.timespec{
914 .tv_sec = math.cast(isize, @divFloor(mtime, std.time.ns_per_s)) catch maxInt(isize),914 .tv_sec = math.cast(isize, @divFloor(mtime, std.time.ns_per_s)) orelse maxInt(isize),
915 .tv_nsec = math.cast(isize, @mod(mtime, std.time.ns_per_s)) catch maxInt(isize),915 .tv_nsec = math.cast(isize, @mod(mtime, std.time.ns_per_s)) orelse maxInt(isize),
916 },916 },
917 };917 };
918 try os.futimens(self.handle, &times);918 try os.futimens(self.handle, &times);
...@@ -1218,7 +1218,7 @@ pub const File = struct {...@@ -1218,7 +1218,7 @@ pub const File = struct {
1218 pub const CopyRangeError = os.CopyFileRangeError;1218 pub const CopyRangeError = os.CopyFileRangeError;
12191219
1220 pub fn copyRange(in: File, in_offset: u64, out: File, out_offset: u64, len: u64) CopyRangeError!u64 {1220 pub fn copyRange(in: File, in_offset: u64, out: File, out_offset: u64, len: u64) CopyRangeError!u64 {
1221 const adjusted_len = math.cast(usize, len) catch math.maxInt(usize);1221 const adjusted_len = math.cast(usize, len) orelse math.maxInt(usize);
1222 const result = try os.copy_file_range(in.handle, in_offset, out.handle, out_offset, adjusted_len, 0);1222 const result = try os.copy_file_range(in.handle, in_offset, out.handle, out_offset, adjusted_len, 0);
1223 return result;1223 return result;
1224 }1224 }
lib/std/io/fixed_buffer_stream.zig+3-3
...@@ -76,20 +76,20 @@ pub fn FixedBufferStream(comptime Buffer: type) type {...@@ -76,20 +76,20 @@ pub fn FixedBufferStream(comptime Buffer: type) type {
76 }76 }
7777
78 pub fn seekTo(self: *Self, pos: u64) SeekError!void {78 pub fn seekTo(self: *Self, pos: u64) SeekError!void {
79 self.pos = if (std.math.cast(usize, pos)) |x| std.math.min(self.buffer.len, x) else |_| self.buffer.len;79 self.pos = if (std.math.cast(usize, pos)) |x| std.math.min(self.buffer.len, x) else self.buffer.len;
80 }80 }
8181
82 pub fn seekBy(self: *Self, amt: i64) SeekError!void {82 pub fn seekBy(self: *Self, amt: i64) SeekError!void {
83 if (amt < 0) {83 if (amt < 0) {
84 const abs_amt = std.math.absCast(amt);84 const abs_amt = std.math.absCast(amt);
85 const abs_amt_usize = std.math.cast(usize, abs_amt) catch std.math.maxInt(usize);85 const abs_amt_usize = std.math.cast(usize, abs_amt) orelse std.math.maxInt(usize);
86 if (abs_amt_usize > self.pos) {86 if (abs_amt_usize > self.pos) {
87 self.pos = 0;87 self.pos = 0;
88 } else {88 } else {
89 self.pos -= abs_amt_usize;89 self.pos -= abs_amt_usize;
90 }90 }
91 } else {91 } else {
92 const amt_usize = std.math.cast(usize, amt) catch std.math.maxInt(usize);92 const amt_usize = std.math.cast(usize, amt) orelse std.math.maxInt(usize);
93 const new_pos = std.math.add(usize, self.pos, amt_usize) catch std.math.maxInt(usize);93 const new_pos = std.math.add(usize, self.pos, amt_usize) catch std.math.maxInt(usize);
94 self.pos = std.math.min(self.buffer.len, new_pos);94 self.pos = std.math.min(self.buffer.len, new_pos);
95 }95 }
lib/std/math.zig+10-11
...@@ -989,28 +989,27 @@ test "negateCast" {...@@ -989,28 +989,27 @@ test "negateCast" {
989}989}
990990
991/// Cast an integer to a different integer type. If the value doesn't fit,991/// Cast an integer to a different integer type. If the value doesn't fit,
992/// return an error.992/// return null.
993/// TODO make this an optional not an error.993pub fn cast(comptime T: type, x: anytype) ?T {
994pub fn cast(comptime T: type, x: anytype) (error{Overflow}!T) {
995 comptime assert(@typeInfo(T) == .Int); // must pass an integer994 comptime assert(@typeInfo(T) == .Int); // must pass an integer
996 comptime assert(@typeInfo(@TypeOf(x)) == .Int); // must pass an integer995 comptime assert(@typeInfo(@TypeOf(x)) == .Int); // must pass an integer
997 if (maxInt(@TypeOf(x)) > maxInt(T) and x > maxInt(T)) {996 if (maxInt(@TypeOf(x)) > maxInt(T) and x > maxInt(T)) {
998 return error.Overflow;997 return null;
999 } else if (minInt(@TypeOf(x)) < minInt(T) and x < minInt(T)) {998 } else if (minInt(@TypeOf(x)) < minInt(T) and x < minInt(T)) {
1000 return error.Overflow;999 return null;
1001 } else {1000 } else {
1002 return @intCast(T, x);1001 return @intCast(T, x);
1003 }1002 }
1004}1003}
10051004
1006test "cast" {1005test "cast" {
1007 try testing.expectError(error.Overflow, cast(u8, @as(u32, 300)));1006 try testing.expect(cast(u8, @as(u32, 300)) == null);
1008 try testing.expectError(error.Overflow, cast(i8, @as(i32, -200)));1007 try testing.expect(cast(i8, @as(i32, -200)) == null);
1009 try testing.expectError(error.Overflow, cast(u8, @as(i8, -1)));1008 try testing.expect(cast(u8, @as(i8, -1)) == null);
1010 try testing.expectError(error.Overflow, cast(u64, @as(i8, -1)));1009 try testing.expect(cast(u64, @as(i8, -1)) == null);
10111010
1012 try testing.expect((try cast(u8, @as(u32, 255))) == @as(u8, 255));1011 try testing.expect(cast(u8, @as(u32, 255)).? == @as(u8, 255));
1013 try testing.expect(@TypeOf(try cast(u8, @as(u32, 255))) == u8);1012 try testing.expect(@TypeOf(cast(u8, @as(u32, 255)).?) == u8);
1014}1013}
10151014
1016pub const AlignCastError = error{UnalignedMemory};1015pub const AlignCastError = error{UnalignedMemory};
lib/std/math/big/int.zig+1-1
...@@ -2014,7 +2014,7 @@ pub const Const = struct {...@@ -2014,7 +2014,7 @@ pub const Const = struct {
2014 } else {2014 } else {
2015 if (math.cast(T, r)) |ok| {2015 if (math.cast(T, r)) |ok| {
2016 return -ok;2016 return -ok;
2017 } else |_| {2017 } else {
2018 return minInt(T);2018 return minInt(T);
2019 }2019 }
2020 }2020 }
lib/std/os.zig+14-16
...@@ -660,7 +660,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {...@@ -660,7 +660,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
660 else => |err| return unexpectedErrno(err),660 else => |err| return unexpectedErrno(err),
661 }661 }
662 }662 }
663 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);663 const iov_count = math.cast(u31, iov.len) orelse math.maxInt(u31);
664 while (true) {664 while (true) {
665 // TODO handle the case when iov_len is too large and get rid of this @intCast665 // TODO handle the case when iov_len is too large and get rid of this @intCast
666 const rc = system.readv(fd, iov.ptr, iov_count);666 const rc = system.readv(fd, iov.ptr, iov_count);
...@@ -877,7 +877,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {...@@ -877,7 +877,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
877 }877 }
878 }878 }
879879
880 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);880 const iov_count = math.cast(u31, iov.len) orelse math.maxInt(u31);
881881
882 const preadv_sym = if (builtin.os.tag == .linux and builtin.link_libc)882 const preadv_sym = if (builtin.os.tag == .linux and builtin.link_libc)
883 system.preadv64883 system.preadv64
...@@ -4163,9 +4163,9 @@ pub fn kevent(...@@ -4163,9 +4163,9 @@ pub fn kevent(
4163 const rc = system.kevent(4163 const rc = system.kevent(
4164 kq,4164 kq,
4165 changelist.ptr,4165 changelist.ptr,
4166 try math.cast(c_int, changelist.len),4166 math.cast(c_int, changelist.len) orelse return error.Overflow,
4167 eventlist.ptr,4167 eventlist.ptr,
4168 try math.cast(c_int, eventlist.len),4168 math.cast(c_int, eventlist.len) orelse return error.Overflow,
4169 timeout,4169 timeout,
4170 );4170 );
4171 switch (errno(rc)) {4171 switch (errno(rc)) {
...@@ -4531,9 +4531,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32...@@ -4531,9 +4531,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32
4531 return;4531 return;
4532 }4532 }
45334533
4534 const path_len_bytes = math.cast(u16, mem.sliceTo(sub_path_w, 0).len * 2) catch |err| switch (err) {4534 const path_len_bytes = math.cast(u16, mem.sliceTo(sub_path_w, 0).len * 2) orelse return error.NameTooLong;
4535 error.Overflow => return error.NameTooLong,
4536 };
4537 var nt_name = windows.UNICODE_STRING{4535 var nt_name = windows.UNICODE_STRING{
4538 .Length = path_len_bytes,4536 .Length = path_len_bytes,
4539 .MaximumLength = path_len_bytes,4537 .MaximumLength = path_len_bytes,
...@@ -4650,7 +4648,7 @@ pub fn sysctl(...@@ -4650,7 +4648,7 @@ pub fn sysctl(
4650 @panic("unsupported"); // TODO should be compile error, not panic4648 @panic("unsupported"); // TODO should be compile error, not panic
4651 }4649 }
46524650
4653 const name_len = math.cast(c_uint, name.len) catch return error.NameTooLong;4651 const name_len = math.cast(c_uint, name.len) orelse return error.NameTooLong;
4654 switch (errno(system.sysctl(name.ptr, name_len, oldp, oldlenp, newp, newlen))) {4652 switch (errno(system.sysctl(name.ptr, name_len, oldp, oldlenp, newp, newlen))) {
4655 .SUCCESS => return,4653 .SUCCESS => return,
4656 .FAULT => unreachable,4654 .FAULT => unreachable,
...@@ -5191,8 +5189,8 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5191,8 +5189,8 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5191/// Spurious wakeups are possible and no precision of timing is guaranteed.5189/// Spurious wakeups are possible and no precision of timing is guaranteed.
5192pub fn nanosleep(seconds: u64, nanoseconds: u64) void {5190pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
5193 var req = timespec{5191 var req = timespec{
5194 .tv_sec = math.cast(isize, seconds) catch math.maxInt(isize),5192 .tv_sec = math.cast(isize, seconds) orelse math.maxInt(isize),
5195 .tv_nsec = math.cast(isize, nanoseconds) catch math.maxInt(isize),5193 .tv_nsec = math.cast(isize, nanoseconds) orelse math.maxInt(isize),
5196 };5194 };
5197 var rem: timespec = undefined;5195 var rem: timespec = undefined;
5198 while (true) {5196 while (true) {
...@@ -6006,10 +6004,10 @@ pub fn sendfile(...@@ -6006,10 +6004,10 @@ pub fn sendfile(
6006 if (headers.len != 0 or trailers.len != 0) {6004 if (headers.len != 0 or trailers.len != 0) {
6007 // Here we carefully avoid `@intCast` by returning partial writes when6005 // Here we carefully avoid `@intCast` by returning partial writes when
6008 // too many io vectors are provided.6006 // too many io vectors are provided.
6009 const hdr_cnt = math.cast(u31, headers.len) catch math.maxInt(u31);6007 const hdr_cnt = math.cast(u31, headers.len) orelse math.maxInt(u31);
6010 if (headers.len > hdr_cnt) return writev(out_fd, headers);6008 if (headers.len > hdr_cnt) return writev(out_fd, headers);
60116009
6012 const trl_cnt = math.cast(u31, trailers.len) catch math.maxInt(u31);6010 const trl_cnt = math.cast(u31, trailers.len) orelse math.maxInt(u31);
60136011
6014 hdtr_data = std.c.sf_hdtr{6012 hdtr_data = std.c.sf_hdtr{
6015 .headers = headers.ptr,6013 .headers = headers.ptr,
...@@ -6085,10 +6083,10 @@ pub fn sendfile(...@@ -6085,10 +6083,10 @@ pub fn sendfile(
6085 if (headers.len != 0 or trailers.len != 0) {6083 if (headers.len != 0 or trailers.len != 0) {
6086 // Here we carefully avoid `@intCast` by returning partial writes when6084 // Here we carefully avoid `@intCast` by returning partial writes when
6087 // too many io vectors are provided.6085 // too many io vectors are provided.
6088 const hdr_cnt = math.cast(u31, headers.len) catch math.maxInt(u31);6086 const hdr_cnt = math.cast(u31, headers.len) orelse math.maxInt(u31);
6089 if (headers.len > hdr_cnt) return writev(out_fd, headers);6087 if (headers.len > hdr_cnt) return writev(out_fd, headers);
60906088
6091 const trl_cnt = math.cast(u31, trailers.len) catch math.maxInt(u31);6089 const trl_cnt = math.cast(u31, trailers.len) orelse math.maxInt(u31);
60926090
6093 hdtr_data = std.c.sf_hdtr{6091 hdtr_data = std.c.sf_hdtr{
6094 .headers = headers.ptr,6092 .headers = headers.ptr,
...@@ -6276,7 +6274,7 @@ pub const PollError = error{...@@ -6276,7 +6274,7 @@ pub const PollError = error{
62766274
6277pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {6275pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {
6278 while (true) {6276 while (true) {
6279 const fds_count = math.cast(nfds_t, fds.len) catch return error.SystemResources;6277 const fds_count = math.cast(nfds_t, fds.len) orelse return error.SystemResources;
6280 const rc = system.poll(fds.ptr, fds_count, timeout);6278 const rc = system.poll(fds.ptr, fds_count, timeout);
6281 if (builtin.os.tag == .windows) {6279 if (builtin.os.tag == .windows) {
6282 if (rc == windows.ws2_32.SOCKET_ERROR) {6280 if (rc == windows.ws2_32.SOCKET_ERROR) {
...@@ -6319,7 +6317,7 @@ pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) P...@@ -6319,7 +6317,7 @@ pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) P
6319 ts_ptr = &ts;6317 ts_ptr = &ts;
6320 ts = timeout_ns.*;6318 ts = timeout_ns.*;
6321 }6319 }
6322 const fds_count = math.cast(nfds_t, fds.len) catch return error.SystemResources;6320 const fds_count = math.cast(nfds_t, fds.len) orelse return error.SystemResources;
6323 const rc = system.ppoll(fds.ptr, fds_count, ts_ptr, mask);6321 const rc = system.ppoll(fds.ptr, fds_count, ts_ptr, mask);
6324 switch (errno(rc)) {6322 switch (errno(rc)) {
6325 .SUCCESS => return @intCast(usize, rc),6323 .SUCCESS => return @intCast(usize, rc),
lib/std/os/windows.zig+7-15
...@@ -78,9 +78,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN...@@ -78,9 +78,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
7878
79 var result: HANDLE = undefined;79 var result: HANDLE = undefined;
8080
81 const path_len_bytes = math.cast(u16, sub_path_w.len * 2) catch |err| switch (err) {81 const path_len_bytes = math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;
82 error.Overflow => return error.NameTooLong,
83 };
84 var nt_name = UNICODE_STRING{82 var nt_name = UNICODE_STRING{
85 .Length = path_len_bytes,83 .Length = path_len_bytes,
86 .MaximumLength = path_len_bytes,84 .MaximumLength = path_len_bytes,
...@@ -551,7 +549,7 @@ pub fn WriteFile(...@@ -551,7 +549,7 @@ pub fn WriteFile(
551 };549 };
552 loop.beginOneEvent();550 loop.beginOneEvent();
553 suspend {551 suspend {
554 const adjusted_len = math.cast(DWORD, bytes.len) catch maxInt(DWORD);552 const adjusted_len = math.cast(DWORD, bytes.len) orelse maxInt(DWORD);
555 _ = kernel32.WriteFile(handle, bytes.ptr, adjusted_len, null, &resume_node.base.overlapped);553 _ = kernel32.WriteFile(handle, bytes.ptr, adjusted_len, null, &resume_node.base.overlapped);
556 }554 }
557 var bytes_transferred: DWORD = undefined;555 var bytes_transferred: DWORD = undefined;
...@@ -589,7 +587,7 @@ pub fn WriteFile(...@@ -589,7 +587,7 @@ pub fn WriteFile(
589 };587 };
590 break :blk &overlapped_data;588 break :blk &overlapped_data;
591 } else null;589 } else null;
592 const adjusted_len = math.cast(u32, bytes.len) catch maxInt(u32);590 const adjusted_len = math.cast(u32, bytes.len) orelse maxInt(u32);
593 if (kernel32.WriteFile(handle, bytes.ptr, adjusted_len, &bytes_written, overlapped) == 0) {591 if (kernel32.WriteFile(handle, bytes.ptr, adjusted_len, &bytes_written, overlapped) == 0) {
594 switch (kernel32.GetLastError()) {592 switch (kernel32.GetLastError()) {
595 .INVALID_USER_BUFFER => return error.SystemResources,593 .INVALID_USER_BUFFER => return error.SystemResources,
...@@ -618,9 +616,7 @@ pub const SetCurrentDirectoryError = error{...@@ -618,9 +616,7 @@ pub const SetCurrentDirectoryError = error{
618};616};
619617
620pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void {618pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void {
621 const path_len_bytes = math.cast(u16, path_name.len * 2) catch |err| switch (err) {619 const path_len_bytes = math.cast(u16, path_name.len * 2) orelse return error.NameTooLong;
622 error.Overflow => return error.NameTooLong,
623 };
624620
625 var nt_name = UNICODE_STRING{621 var nt_name = UNICODE_STRING{
626 .Length = path_len_bytes,622 .Length = path_len_bytes,
...@@ -753,9 +749,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin...@@ -753,9 +749,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin
753 // With the latter, we'd need to call `NtCreateFile` twice, once for file symlink, and if that749 // With the latter, we'd need to call `NtCreateFile` twice, once for file symlink, and if that
754 // failed, again for dir symlink. Omitting any mention of file/dir flags makes it possible750 // failed, again for dir symlink. Omitting any mention of file/dir flags makes it possible
755 // to open the symlink there and then.751 // to open the symlink there and then.
756 const path_len_bytes = math.cast(u16, sub_path_w.len * 2) catch |err| switch (err) {752 const path_len_bytes = math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;
757 error.Overflow => return error.NameTooLong,
758 };
759 var nt_name = UNICODE_STRING{753 var nt_name = UNICODE_STRING{
760 .Length = path_len_bytes,754 .Length = path_len_bytes,
761 .MaximumLength = path_len_bytes,755 .MaximumLength = path_len_bytes,
...@@ -1013,9 +1007,7 @@ pub fn QueryObjectName(...@@ -1013,9 +1007,7 @@ pub fn QueryObjectName(
10131007
1014 const info = @ptrCast(*OBJECT_NAME_INFORMATION, out_buffer_aligned);1008 const info = @ptrCast(*OBJECT_NAME_INFORMATION, out_buffer_aligned);
1015 //buffer size is specified in bytes1009 //buffer size is specified in bytes
1016 const out_buffer_len = std.math.cast(ULONG, out_buffer_aligned.len * 2) catch |e| switch (e) {1010 const out_buffer_len = std.math.cast(ULONG, out_buffer_aligned.len * 2) orelse std.math.maxInt(ULONG);
1017 error.Overflow => std.math.maxInt(ULONG),
1018 };
1019 //last argument would return the length required for full_buffer, not exposed here1011 //last argument would return the length required for full_buffer, not exposed here
1020 const rc = ntdll.NtQueryObject(handle, .ObjectNameInformation, info, out_buffer_len, null);1012 const rc = ntdll.NtQueryObject(handle, .ObjectNameInformation, info, out_buffer_len, null);
1021 switch (rc) {1013 switch (rc) {
...@@ -1221,7 +1213,7 @@ pub fn QueryInformationFile(...@@ -1221,7 +1213,7 @@ pub fn QueryInformationFile(
1221 out_buffer: []u8,1213 out_buffer: []u8,
1222) QueryInformationFileError!void {1214) QueryInformationFileError!void {
1223 var io: IO_STATUS_BLOCK = undefined;1215 var io: IO_STATUS_BLOCK = undefined;
1224 const len_bytes = std.math.cast(u32, out_buffer.len) catch unreachable;1216 const len_bytes = std.math.cast(u32, out_buffer.len) orelse unreachable;
1225 const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class);1217 const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class);
1226 switch (rc) {1218 switch (rc) {
1227 .SUCCESS => {},1219 .SUCCESS => {},
lib/std/time.zig+1-1
...@@ -16,7 +16,7 @@ pub fn sleep(nanoseconds: u64) void {...@@ -16,7 +16,7 @@ pub fn sleep(nanoseconds: u64) void {
1616
17 if (builtin.os.tag == .windows) {17 if (builtin.os.tag == .windows) {
18 const big_ms_from_ns = nanoseconds / ns_per_ms;18 const big_ms_from_ns = nanoseconds / ns_per_ms;
19 const ms = math.cast(os.windows.DWORD, big_ms_from_ns) catch math.maxInt(os.windows.DWORD);19 const ms = math.cast(os.windows.DWORD, big_ms_from_ns) orelse math.maxInt(os.windows.DWORD);
20 os.windows.kernel32.Sleep(ms);20 os.windows.kernel32.Sleep(ms);
21 return;21 return;
22 }22 }
lib/std/zig/system/NativeTargetInfo.zig+1-3
...@@ -657,9 +657,7 @@ pub fn abiAndDynamicLinkerFromFile(...@@ -657,9 +657,7 @@ pub fn abiAndDynamicLinkerFromFile(
657 const strtab_read_len = try preadMin(file, &strtab_buf, ds.offset, strtab_len);657 const strtab_read_len = try preadMin(file, &strtab_buf, ds.offset, strtab_len);
658 const strtab = strtab_buf[0..strtab_read_len];658 const strtab = strtab_buf[0..strtab_read_len];
659 // TODO this pointer cast should not be necessary659 // TODO this pointer cast should not be necessary
660 const rpoff_usize = std.math.cast(usize, rpoff) catch |err| switch (err) {660 const rpoff_usize = std.math.cast(usize, rpoff) orelse return error.InvalidElfFile;
661 error.Overflow => return error.InvalidElfFile,
662 };
663 const rpath_list = mem.sliceTo(std.meta.assumeSentinel(strtab[rpoff_usize..].ptr, 0), 0);661 const rpath_list = mem.sliceTo(std.meta.assumeSentinel(strtab[rpoff_usize..].ptr, 0), 0);
664 var it = mem.tokenize(u8, rpath_list, ":");662 var it = mem.tokenize(u8, rpath_list, ":");
665 while (it.next()) |rpath| {663 while (it.next()) |rpath| {
src/Module.zig+2-2
...@@ -4395,7 +4395,7 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb...@@ -4395,7 +4395,7 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb
4395 .inode = actual_stat.inode,4395 .inode = actual_stat.inode,
4396 .mtime = actual_stat.mtime,4396 .mtime = actual_stat.mtime,
4397 };4397 };
4398 const size_usize = try std.math.cast(usize, actual_stat.size);4398 const size_usize = std.math.cast(usize, actual_stat.size) orelse return error.Overflow;
4399 const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0);4399 const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0);
4400 errdefer gpa.free(bytes);4400 errdefer gpa.free(bytes);
44014401
...@@ -4435,7 +4435,7 @@ pub fn detectEmbedFileUpdate(mod: *Module, embed_file: *EmbedFile) !void {...@@ -4435,7 +4435,7 @@ pub fn detectEmbedFileUpdate(mod: *Module, embed_file: *EmbedFile) !void {
4435 if (unchanged_metadata) return;4435 if (unchanged_metadata) return;
44364436
4437 const gpa = mod.gpa;4437 const gpa = mod.gpa;
4438 const size_usize = try std.math.cast(usize, stat.size);4438 const size_usize = std.math.cast(usize, stat.size) orelse return error.Overflow;
4439 const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0);4439 const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0);
4440 gpa.free(embed_file.bytes);4440 gpa.free(embed_file.bytes);
4441 embed_file.bytes = bytes;4441 embed_file.bytes = bytes;
src/Sema.zig+2-6
...@@ -21786,9 +21786,7 @@ fn cmpNumeric(...@@ -21786,9 +21786,7 @@ fn cmpNumeric(
2178621786
21787 const dest_ty = if (dest_float_type) |ft| ft else blk: {21787 const dest_ty = if (dest_float_type) |ft| ft else blk: {
21788 const max_bits = std.math.max(lhs_bits, rhs_bits);21788 const max_bits = std.math.max(lhs_bits, rhs_bits);
21789 const casted_bits = std.math.cast(u16, max_bits) catch |err| switch (err) {21789 const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits});
21790 error.Overflow => return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits}),
21791 };
21792 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;21790 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
21793 break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);21791 break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);
21794 };21792 };
...@@ -24073,9 +24071,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -24073,9 +24071,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
24073/// is too big to fit.24071/// is too big to fit.
24074fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError!usize {24072fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError!usize {
24075 if (@bitSizeOf(u64) <= @bitSizeOf(usize)) return int;24073 if (@bitSizeOf(u64) <= @bitSizeOf(usize)) return int;
24076 return std.math.cast(usize, int) catch |err| switch (err) {24074 return std.math.cast(usize, int) orelse return sema.fail(block, src, "expression produces integer value {d} which is too big for this compiler implementation to handle", .{int});
24077 error.Overflow => return sema.fail(block, src, "expression produces integer value {d} which is too big for this compiler implementation to handle", .{int}),
24078 };
24079}24075}
2408024076
24081/// For pointer-like optionals, it returns the pointer type. For pointers,24077/// For pointer-like optionals, it returns the pointer type. For pointers,
src/arch/aarch64/CodeGen.zig+5-5
...@@ -453,7 +453,7 @@ fn gen(self: *Self) !void {...@@ -453,7 +453,7 @@ fn gen(self: *Self) !void {
453 .tag = .sub_immediate,453 .tag = .sub_immediate,
454 .data = .{ .rr_imm12_sh = .{ .rd = .sp, .rn = .sp, .imm12 = size } },454 .data = .{ .rr_imm12_sh = .{ .rd = .sp, .rn = .sp, .imm12 = size } },
455 });455 });
456 } else |_| {456 } else {
457 return self.failSymbol("TODO AArch64: allow larger stacks", .{});457 return self.failSymbol("TODO AArch64: allow larger stacks", .{});
458 }458 }
459459
...@@ -860,7 +860,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -860,7 +860,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
860 return @as(u32, 0);860 return @as(u32, 0);
861 }861 }
862862
863 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {863 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
864 const mod = self.bin_file.options.module.?;864 const mod = self.bin_file.options.module.?;
865 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});865 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
866 };866 };
...@@ -871,7 +871,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -871,7 +871,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
871871
872fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {872fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
873 const elem_ty = self.air.typeOfIndex(inst);873 const elem_ty = self.air.typeOfIndex(inst);
874 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {874 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
875 const mod = self.bin_file.options.module.?;875 const mod = self.bin_file.options.module.?;
876 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});876 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
877 };877 };
...@@ -3031,7 +3031,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -3031,7 +3031,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
3031 // Copy registers to the stack3031 // Copy registers to the stack
3032 .register => |reg| blk: {3032 .register => |reg| blk: {
3033 const mod = self.bin_file.options.module.?;3033 const mod = self.bin_file.options.module.?;
3034 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {3034 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) orelse {
3035 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});3035 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
3036 };3036 };
3037 const abi_align = ty.abiAlignment(self.target.*);3037 const abi_align = ty.abiAlignment(self.target.*);
...@@ -4173,7 +4173,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -4173,7 +4173,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
4173 },4173 },
4174 .ptr_stack_offset => |off| {4174 .ptr_stack_offset => |off| {
4175 // TODO: maybe addressing from sp instead of fp4175 // TODO: maybe addressing from sp instead of fp
4176 const imm12 = math.cast(u12, off) catch4176 const imm12 = math.cast(u12, off) orelse
4177 return self.fail("TODO larger stack offsets", .{});4177 return self.fail("TODO larger stack offsets", .{});
41784178
4179 _ = try self.addInst(.{4179 _ = try self.addInst(.{
src/arch/aarch64/Emit.zig+6-6
...@@ -216,21 +216,21 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {...@@ -216,21 +216,21 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {
216 .cbz => {216 .cbz => {
217 if (std.math.cast(i19, @shrExact(offset, 2))) |_| {217 if (std.math.cast(i19, @shrExact(offset, 2))) |_| {
218 return BranchType.cbz;218 return BranchType.cbz;
219 } else |_| {219 } else {
220 return emit.fail("TODO support cbz branches larger than +-1 MiB", .{});220 return emit.fail("TODO support cbz branches larger than +-1 MiB", .{});
221 }221 }
222 },222 },
223 .b, .bl => {223 .b, .bl => {
224 if (std.math.cast(i26, @shrExact(offset, 2))) |_| {224 if (std.math.cast(i26, @shrExact(offset, 2))) |_| {
225 return BranchType.unconditional_branch_immediate;225 return BranchType.unconditional_branch_immediate;
226 } else |_| {226 } else {
227 return emit.fail("TODO support unconditional branches larger than +-128 MiB", .{});227 return emit.fail("TODO support unconditional branches larger than +-128 MiB", .{});
228 }228 }
229 },229 },
230 .b_cond => {230 .b_cond => {
231 if (std.math.cast(i19, @shrExact(offset, 2))) |_| {231 if (std.math.cast(i19, @shrExact(offset, 2))) |_| {
232 return BranchType.b_cond;232 return BranchType.b_cond;
233 } else |_| {233 } else {
234 return emit.fail("TODO support conditional branches larger than +-1 MiB", .{});234 return emit.fail("TODO support conditional branches larger than +-1 MiB", .{});
235 }235 }
236 },236 },
...@@ -927,7 +927,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -927,7 +927,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
927 .ldrb_stack, .ldrsb_stack, .strb_stack => blk: {927 .ldrb_stack, .ldrsb_stack, .strb_stack => blk: {
928 if (math.cast(u12, raw_offset)) |imm| {928 if (math.cast(u12, raw_offset)) |imm| {
929 break :blk Instruction.LoadStoreOffset.imm(imm);929 break :blk Instruction.LoadStoreOffset.imm(imm);
930 } else |_| {930 } else {
931 return emit.fail("TODO load/store stack byte with larger offset", .{});931 return emit.fail("TODO load/store stack byte with larger offset", .{});
932 }932 }
933 },933 },
...@@ -935,7 +935,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -935,7 +935,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
935 assert(std.mem.isAlignedGeneric(u32, raw_offset, 2)); // misaligned stack entry935 assert(std.mem.isAlignedGeneric(u32, raw_offset, 2)); // misaligned stack entry
936 if (math.cast(u12, @divExact(raw_offset, 2))) |imm| {936 if (math.cast(u12, @divExact(raw_offset, 2))) |imm| {
937 break :blk Instruction.LoadStoreOffset.imm(imm);937 break :blk Instruction.LoadStoreOffset.imm(imm);
938 } else |_| {938 } else {
939 return emit.fail("TODO load/store stack halfword with larger offset", .{});939 return emit.fail("TODO load/store stack halfword with larger offset", .{});
940 }940 }
941 },941 },
...@@ -949,7 +949,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -949,7 +949,7 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
949 assert(std.mem.isAlignedGeneric(u32, raw_offset, alignment)); // misaligned stack entry949 assert(std.mem.isAlignedGeneric(u32, raw_offset, alignment)); // misaligned stack entry
950 if (math.cast(u12, @divExact(raw_offset, alignment))) |imm| {950 if (math.cast(u12, @divExact(raw_offset, alignment))) |imm| {
951 break :blk Instruction.LoadStoreOffset.imm(imm);951 break :blk Instruction.LoadStoreOffset.imm(imm);
952 } else |_| {952 } else {
953 return emit.fail("TODO load/store stack with larger offset", .{});953 return emit.fail("TODO load/store stack with larger offset", .{});
954 }954 }
955 },955 },
src/arch/arm/CodeGen.zig+4-4
...@@ -850,7 +850,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -850,7 +850,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
850 return @as(u32, 0);850 return @as(u32, 0);
851 }851 }
852852
853 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {853 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
854 const mod = self.bin_file.options.module.?;854 const mod = self.bin_file.options.module.?;
855 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});855 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
856 };856 };
...@@ -861,7 +861,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -861,7 +861,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
861861
862fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {862fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
863 const elem_ty = self.air.typeOfIndex(inst);863 const elem_ty = self.air.typeOfIndex(inst);
864 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {864 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
865 const mod = self.bin_file.options.module.?;865 const mod = self.bin_file.options.module.?;
866 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});866 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
867 };867 };
...@@ -4299,7 +4299,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -4299,7 +4299,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
4299 1, 4 => {4299 1, 4 => {
4300 const offset = if (math.cast(u12, stack_offset)) |imm| blk: {4300 const offset = if (math.cast(u12, stack_offset)) |imm| blk: {
4301 break :blk Instruction.Offset.imm(imm);4301 break :blk Instruction.Offset.imm(imm);
4302 } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }), .none);4302 } else Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }), .none);
43034303
4304 const tag: Mir.Inst.Tag = switch (abi_size) {4304 const tag: Mir.Inst.Tag = switch (abi_size) {
4305 1 => .strb,4305 1 => .strb,
...@@ -4707,7 +4707,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -4707,7 +4707,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
4707 1, 4 => {4707 1, 4 => {
4708 const offset = if (math.cast(u12, stack_offset)) |imm| blk: {4708 const offset = if (math.cast(u12, stack_offset)) |imm| blk: {
4709 break :blk Instruction.Offset.imm(imm);4709 break :blk Instruction.Offset.imm(imm);
4710 } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }), .none);4710 } else Instruction.Offset.reg(try self.copyToTmpRegister(Type.initTag(.u32), MCValue{ .immediate = stack_offset }), .none);
47114711
4712 const tag: Mir.Inst.Tag = switch (abi_size) {4712 const tag: Mir.Inst.Tag = switch (abi_size) {
4713 1 => .strb,4713 1 => .strb,
src/arch/arm/Emit.zig+1-1
...@@ -164,7 +164,7 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {...@@ -164,7 +164,7 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {
164 .b => {164 .b => {
165 if (std.math.cast(i24, @divExact(offset, 4))) |_| {165 if (std.math.cast(i24, @divExact(offset, 4))) |_| {
166 return BranchType.b;166 return BranchType.b;
167 } else |_| {167 } else {
168 return emit.fail("TODO support larger branches", .{});168 return emit.fail("TODO support larger branches", .{});
169 }169 }
170 },170 },
src/arch/riscv64/CodeGen.zig+2-2
...@@ -779,7 +779,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -779,7 +779,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
779/// Use a pointer instruction as the basis for allocating stack memory.779/// Use a pointer instruction as the basis for allocating stack memory.
780fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {780fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
781 const elem_ty = self.air.typeOfIndex(inst).elemType();781 const elem_ty = self.air.typeOfIndex(inst).elemType();
782 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {782 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
783 const mod = self.bin_file.options.module.?;783 const mod = self.bin_file.options.module.?;
784 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});784 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
785 };785 };
...@@ -790,7 +790,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -790,7 +790,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
790790
791fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {791fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
792 const elem_ty = self.air.typeOfIndex(inst);792 const elem_ty = self.air.typeOfIndex(inst);
793 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {793 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
794 const mod = self.bin_file.options.module.?;794 const mod = self.bin_file.options.module.?;
795 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});795 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
796 };796 };
src/arch/sparc64/CodeGen.zig+6-6
...@@ -421,7 +421,7 @@ fn gen(self: *Self) !void {...@@ -421,7 +421,7 @@ fn gen(self: *Self) !void {
421 },421 },
422 },422 },
423 });423 });
424 } else |_| {424 } else {
425 // TODO for large stacks, replace the prologue with:425 // TODO for large stacks, replace the prologue with:
426 // setx stack_size, %g1426 // setx stack_size, %g1
427 // save %sp, %g1, %sp427 // save %sp, %g1, %sp
...@@ -1591,7 +1591,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -1591,7 +1591,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1591 return @as(u32, 0);1591 return @as(u32, 0);
1592 }1592 }
15931593
1594 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {1594 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
1595 const mod = self.bin_file.options.module.?;1595 const mod = self.bin_file.options.module.?;
1596 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1596 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1597 };1597 };
...@@ -1602,7 +1602,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -1602,7 +1602,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
16021602
1603fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {1603fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
1604 const elem_ty = self.air.typeOfIndex(inst);1604 const elem_ty = self.air.typeOfIndex(inst);
1605 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {1605 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
1606 const mod = self.bin_file.options.module.?;1606 const mod = self.bin_file.options.module.?;
1607 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});1607 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1608 };1608 };
...@@ -2299,7 +2299,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -2299,7 +2299,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
2299 return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa });2299 return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa });
2300 },2300 },
2301 .ptr_stack_offset => |off| {2301 .ptr_stack_offset => |off| {
2302 const simm13 = math.cast(u12, off + abi.stack_bias + abi.stack_reserved_area) catch2302 const simm13 = math.cast(u12, off + abi.stack_bias + abi.stack_reserved_area) orelse
2303 return self.fail("TODO larger stack offsets", .{});2303 return self.fail("TODO larger stack offsets", .{});
23042304
2305 _ = try self.addInst(.{2305 _ = try self.addInst(.{
...@@ -2432,7 +2432,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -2432,7 +2432,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
2432 },2432 },
2433 .stack_offset => |off| {2433 .stack_offset => |off| {
2434 const real_offset = off + abi.stack_bias + abi.stack_reserved_area;2434 const real_offset = off + abi.stack_bias + abi.stack_reserved_area;
2435 const simm13 = math.cast(i13, real_offset) catch2435 const simm13 = math.cast(i13, real_offset) orelse
2436 return self.fail("TODO larger stack offsets", .{});2436 return self.fail("TODO larger stack offsets", .{});
2437 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));2437 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));
2438 },2438 },
...@@ -2466,7 +2466,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -2466,7 +2466,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
2466 },2466 },
2467 .register => |reg| {2467 .register => |reg| {
2468 const real_offset = stack_offset + abi.stack_bias + abi.stack_reserved_area;2468 const real_offset = stack_offset + abi.stack_bias + abi.stack_reserved_area;
2469 const simm13 = math.cast(i13, real_offset) catch2469 const simm13 = math.cast(i13, real_offset) orelse
2470 return self.fail("TODO larger stack offsets", .{});2470 return self.fail("TODO larger stack offsets", .{});
2471 return self.genStore(reg, .sp, i13, simm13, abi_size);2471 return self.genStore(reg, .sp, i13, simm13, abi_size);
2472 },2472 },
src/arch/sparc64/Emit.zig+2-2
...@@ -519,14 +519,14 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {...@@ -519,14 +519,14 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {
519 .bpcc => {519 .bpcc => {
520 if (std.math.cast(i21, offset)) |_| {520 if (std.math.cast(i21, offset)) |_| {
521 return BranchType.bpcc;521 return BranchType.bpcc;
522 } else |_| {522 } else {
523 return emit.fail("TODO support BPcc branches larger than +-1 MiB", .{});523 return emit.fail("TODO support BPcc branches larger than +-1 MiB", .{});
524 }524 }
525 },525 },
526 .bpr => {526 .bpr => {
527 if (std.math.cast(i18, offset)) |_| {527 if (std.math.cast(i18, offset)) |_| {
528 return BranchType.bpr;528 return BranchType.bpr;
529 } else |_| {529 } else {
530 return emit.fail("TODO support BPr branches larger than +-128 KiB", .{});530 return emit.fail("TODO support BPr branches larger than +-128 KiB", .{});
531 }531 }
532 },532 },
src/arch/wasm/CodeGen.zig+7-7
...@@ -1163,7 +1163,7 @@ fn allocStack(self: *Self, ty: Type) !WValue {...@@ -1163,7 +1163,7 @@ fn allocStack(self: *Self, ty: Type) !WValue {
1163 try self.initializeStack();1163 try self.initializeStack();
1164 }1164 }
11651165
1166 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) catch {1166 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) orelse {
1167 const module = self.bin_file.base.options.module.?;1167 const module = self.bin_file.base.options.module.?;
1168 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1168 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1169 ty.fmt(module), ty.abiSize(self.target),1169 ty.fmt(module), ty.abiSize(self.target),
...@@ -1198,7 +1198,7 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1198,7 +1198,7 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {
1198 }1198 }
11991199
1200 const abi_alignment = ptr_ty.ptrAlignment(self.target);1200 const abi_alignment = ptr_ty.ptrAlignment(self.target);
1201 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) catch {1201 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) orelse {
1202 const module = self.bin_file.base.options.module.?;1202 const module = self.bin_file.base.options.module.?;
1203 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{1203 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1204 pointee_ty.fmt(module), pointee_ty.abiSize(self.target),1204 pointee_ty.fmt(module), pointee_ty.abiSize(self.target),
...@@ -2695,7 +2695,7 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2695,7 +2695,7 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2695 const extra = self.air.extraData(Air.StructField, ty_pl.payload);2695 const extra = self.air.extraData(Air.StructField, ty_pl.payload);
2696 const struct_ptr = try self.resolveInst(extra.data.struct_operand);2696 const struct_ptr = try self.resolveInst(extra.data.struct_operand);
2697 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();2697 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();
2698 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {2698 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) orelse {
2699 const module = self.bin_file.base.options.module.?;2699 const module = self.bin_file.base.options.module.?;
2700 return self.fail("Field type '{}' too big to fit into stack frame", .{2700 return self.fail("Field type '{}' too big to fit into stack frame", .{
2701 struct_ty.structFieldType(extra.data.field_index).fmt(module),2701 struct_ty.structFieldType(extra.data.field_index).fmt(module),
...@@ -2709,7 +2709,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr...@@ -2709,7 +2709,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr
2709 const struct_ptr = try self.resolveInst(ty_op.operand);2709 const struct_ptr = try self.resolveInst(ty_op.operand);
2710 const struct_ty = self.air.typeOf(ty_op.operand).childType();2710 const struct_ty = self.air.typeOf(ty_op.operand).childType();
2711 const field_ty = struct_ty.structFieldType(index);2711 const field_ty = struct_ty.structFieldType(index);
2712 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {2712 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) orelse {
2713 const module = self.bin_file.base.options.module.?;2713 const module = self.bin_file.base.options.module.?;
2714 return self.fail("Field type '{}' too big to fit into stack frame", .{2714 return self.fail("Field type '{}' too big to fit into stack frame", .{
2715 field_ty.fmt(module),2715 field_ty.fmt(module),
...@@ -2737,7 +2737,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2737,7 +2737,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2737 const field_index = struct_field.field_index;2737 const field_index = struct_field.field_index;
2738 const field_ty = struct_ty.structFieldType(field_index);2738 const field_ty = struct_ty.structFieldType(field_index);
2739 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return WValue{ .none = {} };2739 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return WValue{ .none = {} };
2740 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) catch {2740 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) orelse {
2741 const module = self.bin_file.base.options.module.?;2741 const module = self.bin_file.base.options.module.?;
2742 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(module)});2742 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(module)});
2743 };2743 };
...@@ -3193,7 +3193,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue...@@ -3193,7 +3193,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
3193 return operand;3193 return operand;
3194 }3194 }
31953195
3196 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {3196 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) orelse {
3197 const module = self.bin_file.base.options.module.?;3197 const module = self.bin_file.base.options.module.?;
3198 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(module)});3198 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(module)});
3199 };3199 };
...@@ -3223,7 +3223,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3223,7 +3223,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3223 if (op_ty.optionalReprIsPayload()) {3223 if (op_ty.optionalReprIsPayload()) {
3224 return operand;3224 return operand;
3225 }3225 }
3226 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {3226 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) orelse {
3227 const module = self.bin_file.base.options.module.?;3227 const module = self.bin_file.base.options.module.?;
3228 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(module)});3228 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(module)});
3229 };3229 };
src/arch/x86_64/CodeGen.zig+2-2
...@@ -854,7 +854,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -854,7 +854,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
854 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));854 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));
855 }855 }
856856
857 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {857 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
858 const mod = self.bin_file.options.module.?;858 const mod = self.bin_file.options.module.?;
859 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});859 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
860 };860 };
...@@ -865,7 +865,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -865,7 +865,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
865865
866fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {866fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
867 const elem_ty = self.air.typeOfIndex(inst);867 const elem_ty = self.air.typeOfIndex(inst);
868 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {868 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
869 const mod = self.bin_file.options.module.?;869 const mod = self.bin_file.options.module.?;
870 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});870 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
871 };871 };
src/codegen.zig+9-9
...@@ -166,7 +166,7 @@ pub fn generateSymbol(...@@ -166,7 +166,7 @@ pub fn generateSymbol(
166 });166 });
167167
168 if (typed_value.val.isUndefDeep()) {168 if (typed_value.val.isUndefDeep()) {
169 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));169 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
170 try code.appendNTimes(0xaa, abi_size);170 try code.appendNTimes(0xaa, abi_size);
171 return Result{ .appended = {} };171 return Result{ .appended = {} };
172 }172 }
...@@ -452,7 +452,7 @@ pub fn generateSymbol(...@@ -452,7 +452,7 @@ pub fn generateSymbol(
452 if (info.bits > 64) {452 if (info.bits > 64) {
453 var bigint_buffer: Value.BigIntSpace = undefined;453 var bigint_buffer: Value.BigIntSpace = undefined;
454 const bigint = typed_value.val.toBigInt(&bigint_buffer, target);454 const bigint = typed_value.val.toBigInt(&bigint_buffer, target);
455 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));455 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
456 const start = code.items.len;456 const start = code.items.len;
457 try code.resize(start + abi_size);457 try code.resize(start + abi_size);
458 bigint.writeTwosComplement(code.items[start..][0..abi_size], info.bits, abi_size, endian);458 bigint.writeTwosComplement(code.items[start..][0..abi_size], info.bits, abi_size, endian);
...@@ -571,7 +571,7 @@ pub fn generateSymbol(...@@ -571,7 +571,7 @@ pub fn generateSymbol(
571571
572 // Pad struct members if required572 // Pad struct members if required
573 const padded_field_end = typed_value.ty.structFieldOffset(index + 1, target);573 const padded_field_end = typed_value.ty.structFieldOffset(index + 1, target);
574 const padding = try math.cast(usize, padded_field_end - unpadded_field_end);574 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse return error.Overflow;
575575
576 if (padding > 0) {576 if (padding > 0) {
577 try code.writer().writeByteNTimes(0, padding);577 try code.writer().writeByteNTimes(0, padding);
...@@ -611,7 +611,7 @@ pub fn generateSymbol(...@@ -611,7 +611,7 @@ pub fn generateSymbol(
611 assert(union_ty.haveFieldTypes());611 assert(union_ty.haveFieldTypes());
612 const field_ty = union_ty.fields.values()[field_index].ty;612 const field_ty = union_ty.fields.values()[field_index].ty;
613 if (!field_ty.hasRuntimeBits()) {613 if (!field_ty.hasRuntimeBits()) {
614 try code.writer().writeByteNTimes(0xaa, try math.cast(usize, layout.payload_size));614 try code.writer().writeByteNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
615 } else {615 } else {
616 switch (try generateSymbol(bin_file, src_loc, .{616 switch (try generateSymbol(bin_file, src_loc, .{
617 .ty = field_ty,617 .ty = field_ty,
...@@ -624,7 +624,7 @@ pub fn generateSymbol(...@@ -624,7 +624,7 @@ pub fn generateSymbol(
624 .fail => |em| return Result{ .fail = em },624 .fail => |em| return Result{ .fail = em },
625 }625 }
626626
627 const padding = try math.cast(usize, layout.payload_size - field_ty.abiSize(target));627 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(target)) orelse return error.Overflow;
628 if (padding > 0) {628 if (padding > 0) {
629 try code.writer().writeByteNTimes(0, padding);629 try code.writer().writeByteNTimes(0, padding);
630 }630 }
...@@ -649,8 +649,8 @@ pub fn generateSymbol(...@@ -649,8 +649,8 @@ pub fn generateSymbol(
649 var opt_buf: Type.Payload.ElemType = undefined;649 var opt_buf: Type.Payload.ElemType = undefined;
650 const payload_type = typed_value.ty.optionalChild(&opt_buf);650 const payload_type = typed_value.ty.optionalChild(&opt_buf);
651 const is_pl = !typed_value.val.isNull();651 const is_pl = !typed_value.val.isNull();
652 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));652 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
653 const offset = abi_size - try math.cast(usize, payload_type.abiSize(target));653 const offset = abi_size - (math.cast(usize, payload_type.abiSize(target)) orelse return error.Overflow);
654654
655 if (!payload_type.hasRuntimeBits()) {655 if (!payload_type.hasRuntimeBits()) {
656 try code.writer().writeByteNTimes(@boolToInt(is_pl), abi_size);656 try code.writer().writeByteNTimes(@boolToInt(is_pl), abi_size);
...@@ -758,7 +758,7 @@ pub fn generateSymbol(...@@ -758,7 +758,7 @@ pub fn generateSymbol(
758 }758 }
759 const unpadded_end = code.items.len - begin;759 const unpadded_end = code.items.len - begin;
760 const padded_end = mem.alignForwardGeneric(u64, unpadded_end, abi_align);760 const padded_end = mem.alignForwardGeneric(u64, unpadded_end, abi_align);
761 const padding = try math.cast(usize, padded_end - unpadded_end);761 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
762762
763 if (padding > 0) {763 if (padding > 0) {
764 try code.writer().writeByteNTimes(0, padding);764 try code.writer().writeByteNTimes(0, padding);
...@@ -780,7 +780,7 @@ pub fn generateSymbol(...@@ -780,7 +780,7 @@ pub fn generateSymbol(
780 }780 }
781 const unpadded_end = code.items.len - begin;781 const unpadded_end = code.items.len - begin;
782 const padded_end = mem.alignForwardGeneric(u64, unpadded_end, abi_align);782 const padded_end = mem.alignForwardGeneric(u64, unpadded_end, abi_align);
783 const padding = try math.cast(usize, padded_end - unpadded_end);783 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
784784
785 if (padding > 0) {785 if (padding > 0) {
786 try code.writer().writeByteNTimes(0, padding);786 try code.writer().writeByteNTimes(0, padding);
src/link/MachO.zig+7-7
...@@ -2022,7 +2022,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -2022,7 +2022,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
2022}2022}
20232023
2024pub fn createEmptyAtom(self: *MachO, local_sym_index: u32, size: u64, alignment: u32) !*Atom {2024pub fn createEmptyAtom(self: *MachO, local_sym_index: u32, size: u64, alignment: u32) !*Atom {
2025 const size_usize = try math.cast(usize, size);2025 const size_usize = math.cast(usize, size) orelse return error.Overflow;
2026 const atom = try self.base.allocator.create(Atom);2026 const atom = try self.base.allocator.create(Atom);
2027 errdefer self.base.allocator.destroy(atom);2027 errdefer self.base.allocator.destroy(atom);
2028 atom.* = Atom.empty;2028 atom.* = Atom.empty;
...@@ -2157,7 +2157,7 @@ fn writeAllAtoms(self: *MachO) !void {...@@ -2157,7 +2157,7 @@ fn writeAllAtoms(self: *MachO) !void {
21572157
2158 var buffer = std.ArrayList(u8).init(self.base.allocator);2158 var buffer = std.ArrayList(u8).init(self.base.allocator);
2159 defer buffer.deinit();2159 defer buffer.deinit();
2160 try buffer.ensureTotalCapacity(try math.cast(usize, sect.size));2160 try buffer.ensureTotalCapacity(math.cast(usize, sect.size) orelse return error.Overflow);
21612161
2162 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });2162 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });
21632163
...@@ -2170,7 +2170,7 @@ fn writeAllAtoms(self: *MachO) !void {...@@ -2170,7 +2170,7 @@ fn writeAllAtoms(self: *MachO) !void {
2170 const padding_size: usize = if (atom.next) |next| blk: {2170 const padding_size: usize = if (atom.next) |next| blk: {
2171 const next_sym = self.locals.items[next.local_sym_index];2171 const next_sym = self.locals.items[next.local_sym_index];
2172 const size = next_sym.n_value - (atom_sym.n_value + atom.size);2172 const size = next_sym.n_value - (atom_sym.n_value + atom.size);
2173 break :blk try math.cast(usize, size);2173 break :blk math.cast(usize, size) orelse return error.Overflow;
2174 } else 0;2174 } else 0;
21752175
2176 log.debug(" (adding atom {s} to buffer: {})", .{ self.getString(atom_sym.n_strx), atom_sym });2176 log.debug(" (adding atom {s} to buffer: {})", .{ self.getString(atom_sym.n_strx), atom_sym });
...@@ -2507,7 +2507,7 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {...@@ -2507,7 +2507,7 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {
2507 .aarch64 => {2507 .aarch64 => {
2508 const literal = blk: {2508 const literal = blk: {
2509 const div_res = try math.divExact(u64, stub_size - @sizeOf(u32), 4);2509 const div_res = try math.divExact(u64, stub_size - @sizeOf(u32), 4);
2510 break :blk try math.cast(u18, div_res);2510 break :blk math.cast(u18, div_res) orelse return error.Overflow;
2511 };2511 };
2512 // ldr w16, literal2512 // ldr w16, literal
2513 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldrLiteral(2513 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldrLiteral(
...@@ -5080,7 +5080,7 @@ fn growSegment(self: *MachO, seg_id: u16, new_size: u64) !void {...@@ -5080,7 +5080,7 @@ fn growSegment(self: *MachO, seg_id: u16, new_size: u64) !void {
5080 self.base.file.?,5080 self.base.file.?,
5081 next_seg.inner.fileoff,5081 next_seg.inner.fileoff,
5082 next_seg.inner.fileoff + offset_amt,5082 next_seg.inner.fileoff + offset_amt,
5083 try math.cast(usize, next_seg.inner.filesize),5083 math.cast(usize, next_seg.inner.filesize) orelse return error.Overflow,
5084 );5084 );
50855085
5086 next_seg.inner.fileoff += offset_amt;5086 next_seg.inner.fileoff += offset_amt;
...@@ -5165,7 +5165,7 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void {...@@ -5165,7 +5165,7 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void {
5165 self.base.file.?,5165 self.base.file.?,
5166 next_sect.offset,5166 next_sect.offset,
5167 next_sect.offset + offset_amt,5167 next_sect.offset + offset_amt,
5168 try math.cast(usize, total_size),5168 math.cast(usize, total_size) orelse return error.Overflow,
5169 );5169 );
51705170
5171 var next = match.sect + 1;5171 var next = match.sect + 1;
...@@ -5950,7 +5950,7 @@ fn writeDices(self: *MachO) !void {...@@ -5950,7 +5950,7 @@ fn writeDices(self: *MachO) !void {
5950 while (true) {5950 while (true) {
5951 if (atom.dices.items.len > 0) {5951 if (atom.dices.items.len > 0) {
5952 const sym = self.locals.items[atom.local_sym_index];5952 const sym = self.locals.items[atom.local_sym_index];
5953 const base_off = try math.cast(u32, sym.n_value - text_sect.addr + text_sect.offset);5953 const base_off = math.cast(u32, sym.n_value - text_sect.addr + text_sect.offset) orelse return error.Overflow;
59545954
5955 try buf.ensureUnusedCapacity(atom.dices.items.len * @sizeOf(macho.data_in_code_entry));5955 try buf.ensureUnusedCapacity(atom.dices.items.len * @sizeOf(macho.data_in_code_entry));
5956 for (atom.dices.items) |dice| {5956 for (atom.dices.items) |dice| {
src/link/MachO/Atom.zig+18-20
...@@ -763,17 +763,15 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {...@@ -763,17 +763,15 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
763 const displacement = math.cast(763 const displacement = math.cast(
764 i28,764 i28,
765 @intCast(i64, target_addr) - @intCast(i64, source_addr),765 @intCast(i64, target_addr) - @intCast(i64, source_addr),
766 ) catch |err| switch (err) {766 ) orelse {
767 error.Overflow => {767 log.err("jump too big to encode as i28 displacement value", .{});
768 log.err("jump too big to encode as i28 displacement value", .{});768 log.err(" (target - source) = displacement => 0x{x} - 0x{x} = 0x{x}", .{
769 log.err(" (target - source) = displacement => 0x{x} - 0x{x} = 0x{x}", .{769 target_addr,
770 target_addr,770 source_addr,
771 source_addr,771 @intCast(i64, target_addr) - @intCast(i64, source_addr),
772 @intCast(i64, target_addr) - @intCast(i64, source_addr),772 });
773 });773 log.err(" TODO implement branch islands to extend jump distance for arm64", .{});
774 log.err(" TODO implement branch islands to extend jump distance for arm64", .{});774 return error.TODOImplementBranchIslands;
775 return error.TODOImplementBranchIslands;
776 },
777 };775 };
778 const code = self.code.items[rel.offset..][0..4];776 const code = self.code.items[rel.offset..][0..4];
779 var inst = aarch64.Instruction{777 var inst = aarch64.Instruction{
...@@ -915,7 +913,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {...@@ -915,7 +913,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
915 mem.writeIntLittle(u32, code, inst.toU32());913 mem.writeIntLittle(u32, code, inst.toU32());
916 },914 },
917 .ARM64_RELOC_POINTER_TO_GOT => {915 .ARM64_RELOC_POINTER_TO_GOT => {
918 const result = try math.cast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr));916 const result = math.cast(i32, @intCast(i64, target_addr) - @intCast(i64, source_addr)) orelse return error.Overflow;
919 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, result));917 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, result));
920 },918 },
921 .ARM64_RELOC_UNSIGNED => {919 .ARM64_RELOC_UNSIGNED => {
...@@ -945,17 +943,17 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {...@@ -945,17 +943,17 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
945 .x86_64 => {943 .x86_64 => {
946 switch (@intToEnum(macho.reloc_type_x86_64, rel.@"type")) {944 switch (@intToEnum(macho.reloc_type_x86_64, rel.@"type")) {
947 .X86_64_RELOC_BRANCH => {945 .X86_64_RELOC_BRANCH => {
948 const displacement = try math.cast(946 const displacement = math.cast(
949 i32,947 i32,
950 @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend,948 @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend,
951 );949 ) orelse return error.Overflow;
952 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));950 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));
953 },951 },
954 .X86_64_RELOC_GOT, .X86_64_RELOC_GOT_LOAD => {952 .X86_64_RELOC_GOT, .X86_64_RELOC_GOT_LOAD => {
955 const displacement = try math.cast(953 const displacement = math.cast(
956 i32,954 i32,
957 @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend,955 @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend,
958 );956 ) orelse return error.Overflow;
959 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));957 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));
960 },958 },
961 .X86_64_RELOC_TLV => {959 .X86_64_RELOC_TLV => {
...@@ -963,10 +961,10 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {...@@ -963,10 +961,10 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
963 // We need to rewrite the opcode from movq to leaq.961 // We need to rewrite the opcode from movq to leaq.
964 self.code.items[rel.offset - 2] = 0x8d;962 self.code.items[rel.offset - 2] = 0x8d;
965 }963 }
966 const displacement = try math.cast(964 const displacement = math.cast(
967 i32,965 i32,
968 @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend,966 @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend,
969 );967 ) orelse return error.Overflow;
970 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));968 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));
971 },969 },
972 .X86_64_RELOC_SIGNED,970 .X86_64_RELOC_SIGNED,
...@@ -982,10 +980,10 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {...@@ -982,10 +980,10 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
982 else => unreachable,980 else => unreachable,
983 };981 };
984 const actual_target_addr = @intCast(i64, target_addr) + rel.addend;982 const actual_target_addr = @intCast(i64, target_addr) + rel.addend;
985 const displacement = try math.cast(983 const displacement = math.cast(
986 i32,984 i32,
987 actual_target_addr - @intCast(i64, source_addr + correction + 4),985 actual_target_addr - @intCast(i64, source_addr + correction + 4),
988 );986 ) orelse return error.Overflow;
989 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));987 mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement));
990 },988 },
991 .X86_64_RELOC_UNSIGNED => {989 .X86_64_RELOC_UNSIGNED => {
src/link/MachO/DebugSymbols.zig+2-2
...@@ -616,7 +616,7 @@ fn writeSymbolTable(self: *DebugSymbols) !void {...@@ -616,7 +616,7 @@ fn writeSymbolTable(self: *DebugSymbols) !void {
616 self.file,616 self.file,
617 dwarf_seg.inner.fileoff,617 dwarf_seg.inner.fileoff,
618 dwarf_seg.inner.fileoff + diff,618 dwarf_seg.inner.fileoff + diff,
619 try math.cast(usize, dwarf_seg.inner.filesize),619 math.cast(usize, dwarf_seg.inner.filesize) orelse return error.Overflow,
620 );620 );
621621
622 const old_seg_fileoff = dwarf_seg.inner.fileoff;622 const old_seg_fileoff = dwarf_seg.inner.fileoff;
...@@ -669,7 +669,7 @@ fn writeStringTable(self: *DebugSymbols) !void {...@@ -669,7 +669,7 @@ fn writeStringTable(self: *DebugSymbols) !void {
669 self.file,669 self.file,
670 dwarf_seg.inner.fileoff,670 dwarf_seg.inner.fileoff,
671 dwarf_seg.inner.fileoff + diff,671 dwarf_seg.inner.fileoff + diff,
672 try math.cast(usize, dwarf_seg.inner.filesize),672 math.cast(usize, dwarf_seg.inner.filesize) orelse return error.Overflow,
673 );673 );
674674
675 const old_seg_fileoff = dwarf_seg.inner.fileoff;675 const old_seg_fileoff = dwarf_seg.inner.fileoff;
src/link/MachO/Dylib.zig+1-1
...@@ -83,7 +83,7 @@ pub const Id = struct {...@@ -83,7 +83,7 @@ pub const Id = struct {
83 switch (version) {83 switch (version) {
84 .int => |int| {84 .int => |int| {
85 var out: u32 = 0;85 var out: u32 = 0;
86 const major = try math.cast(u16, int);86 const major = math.cast(u16, int) orelse return error.Overflow;
87 out += @intCast(u32, major) << 16;87 out += @intCast(u32, major) << 16;
88 return out;88 return out;
89 },89 },
src/link/MachO/Object.zig+1-1
...@@ -504,7 +504,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) !...@@ -504,7 +504,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) !
504504
505 for (dices) |dice| {505 for (dices) |dice| {
506 atom.dices.appendAssumeCapacity(.{506 atom.dices.appendAssumeCapacity(.{
507 .offset = dice.offset - try math.cast(u32, sect.addr),507 .offset = dice.offset - (math.cast(u32, sect.addr) orelse return error.Overflow),
508 .length = dice.length,508 .length = dice.length,
509 .kind = dice.kind,509 .kind = dice.kind,
510 });510 });
src/link/tapi/yaml.zig+1-1
...@@ -316,7 +316,7 @@ pub const Yaml = struct {...@@ -316,7 +316,7 @@ pub const Yaml = struct {
316316
317 fn parseValue(self: *Yaml, comptime T: type, value: Value) Error!T {317 fn parseValue(self: *Yaml, comptime T: type, value: Value) Error!T {
318 return switch (@typeInfo(T)) {318 return switch (@typeInfo(T)) {
319 .Int => math.cast(T, try value.asInt()),319 .Int => math.cast(T, try value.asInt()) orelse error.Overflow,
320 .Float => math.lossyCast(T, try value.asFloat()),320 .Float => math.lossyCast(T, try value.asFloat()),
321 .Struct => self.parseStruct(T, try value.asMap()),321 .Struct => self.parseStruct(T, try value.asMap()),
322 .Union => self.parseUnion(T, value),322 .Union => self.parseUnion(T, value),
src/main.zig+1-1
...@@ -4067,7 +4067,7 @@ fn fmtPathFile(...@@ -4067,7 +4067,7 @@ fn fmtPathFile(
4067 const source_code = try readSourceFileToEndAlloc(4067 const source_code = try readSourceFileToEndAlloc(
4068 fmt.gpa,4068 fmt.gpa,
4069 &source_file,4069 &source_file,
4070 std.math.cast(usize, stat.size) catch return error.FileTooBig,4070 std.math.cast(usize, stat.size) orelse return error.FileTooBig,
4071 );4071 );
4072 defer fmt.gpa.free(source_code);4072 defer fmt.gpa.free(source_code);
40734073
src/translate_c.zig+7-9
...@@ -4526,9 +4526,7 @@ fn transCreateNodeBoolInfixOp(...@@ -4526,9 +4526,7 @@ fn transCreateNodeBoolInfixOp(
4526}4526}
45274527
4528fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {4528fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
4529 const num_limbs = math.cast(usize, int.getNumWords()) catch |err| switch (err) {4529 const num_limbs = math.cast(usize, int.getNumWords()) orelse return error.OutOfMemory;
4530 error.Overflow => return error.OutOfMemory,
4531 };
4532 var aps_int = int;4530 var aps_int = int;
4533 const is_negative = int.isSigned() and int.isNegative();4531 const is_negative = int.isSigned() and int.isNegative();
4534 if (is_negative) aps_int = aps_int.negate();4532 if (is_negative) aps_int = aps_int.negate();
...@@ -5627,12 +5625,12 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {...@@ -5627,12 +5625,12 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
5627 // make the output less noisy by skipping promoteIntLiteral where5625 // make the output less noisy by skipping promoteIntLiteral where
5628 // it's guaranteed to not be required because of C standard type constraints5626 // it's guaranteed to not be required because of C standard type constraints
5629 const guaranteed_to_fit = switch (suffix) {5627 const guaranteed_to_fit = switch (suffix) {
5630 .none => !meta.isError(math.cast(i16, value)),5628 .none => math.cast(i16, value) != null,
5631 .u => !meta.isError(math.cast(u16, value)),5629 .u => math.cast(u16, value) != null,
5632 .l => !meta.isError(math.cast(i32, value)),5630 .l => math.cast(i32, value) != null,
5633 .lu => !meta.isError(math.cast(u32, value)),5631 .lu => math.cast(u32, value) != null,
5634 .ll => !meta.isError(math.cast(i64, value)),5632 .ll => math.cast(i64, value) != null,
5635 .llu => !meta.isError(math.cast(u64, value)),5633 .llu => math.cast(u64, value) != null,
5636 .f => unreachable,5634 .f => unreachable,
5637 };5635 };
56385636