authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-02-13 16:19:17+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-02-15 01:43:57+02:00
log7199d7c77715fe06606c5c89595e6852b3fa8c20
tree7ffd59e66cc2074d2da5284c9c22d69ddfc92968
parent4e6f21e2cb2c557b5c019f4acf445665a26edcba

split `@qualCast` into `@constCast` and `@volatileCast`


18 files changed, 126 insertions(+), 87 deletions(-)

doc/langref.html.in+16-8
...@@ -8129,6 +8129,13 @@ test "main" {...@@ -8129,6 +8129,13 @@ test "main" {
8129 {#code_end#}8129 {#code_end#}
8130 {#header_close#}8130 {#header_close#}
81318131
8132 {#header_open|@constCast#}
8133 <pre>{#syntax#}@constCast(value: anytype) DestType{#endsyntax#}</pre>
8134 <p>
8135 Remove {#syntax#}const{#endsyntax#} qualifier from a pointer.
8136 </p>
8137 {#header_close#}
8138
8132 {#header_open|@ctz#}8139 {#header_open|@ctz#}
8133 <pre>{#syntax#}@ctz(operand: anytype){#endsyntax#}</pre>8140 <pre>{#syntax#}@ctz(operand: anytype){#endsyntax#}</pre>
8134 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>8141 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>
...@@ -8814,7 +8821,8 @@ pub const PrefetchOptions = struct {...@@ -8814,7 +8821,8 @@ pub const PrefetchOptions = struct {
8814 {#syntax#}@ptrCast{#endsyntax#} cannot be used for:8821 {#syntax#}@ptrCast{#endsyntax#} cannot be used for:
8815 </p>8822 </p>
8816 <ul>8823 <ul>
8817 <li>Removing {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier, use {#link|@qualCast#}.</li>8824 <li>Removing {#syntax#}const{#endsyntax#} qualifier, use {#link|@constCast#}.</li>
8825 <li>Removing {#syntax#}volatile{#endsyntax#} qualifier, use {#link|@volatileCast#}.</li>
8818 <li>Changing pointer address space, use {#link|@addrSpaceCast#}.</li>8826 <li>Changing pointer address space, use {#link|@addrSpaceCast#}.</li>
8819 <li>Increasing pointer alignment, use {#link|@alignCast#}.</li>8827 <li>Increasing pointer alignment, use {#link|@alignCast#}.</li>
8820 <li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}.</li>8828 <li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}.</li>
...@@ -8831,13 +8839,6 @@ pub const PrefetchOptions = struct {...@@ -8831,13 +8839,6 @@ pub const PrefetchOptions = struct {
88318839
8832 {#header_close#}8840 {#header_close#}
88338841
8834 {#header_open|@qualCast#}
8835 <pre>{#syntax#}@qualCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre>
8836 <p>
8837 Remove {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier from a pointer.
8838 </p>
8839 {#header_close#}
8840
8841 {#header_open|@rem#}8842 {#header_open|@rem#}
8842 <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>8843 <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>
8843 <p>8844 <p>
...@@ -9525,6 +9526,13 @@ fn foo(comptime T: type, ptr: *T) T {...@@ -9525,6 +9526,13 @@ fn foo(comptime T: type, ptr: *T) T {
9525 <pre>{#syntax#}@Vector(len: comptime_int, Element: type) type{#endsyntax#}</pre>9526 <pre>{#syntax#}@Vector(len: comptime_int, Element: type) type{#endsyntax#}</pre>
9526 <p>Creates {#link|Vectors#}.</p>9527 <p>Creates {#link|Vectors#}.</p>
9527 {#header_close#}9528 {#header_close#}
9529
9530 {#header_open|@volatileCast#}
9531 <pre>{#syntax#}@volatileCast(value: anytype) DestType{#endsyntax#}</pre>
9532 <p>
9533 Remove {#syntax#}volatile{#endsyntax#} qualifier from a pointer.
9534 </p>
9535 {#header_close#}
9528 {#header_close#}9536 {#header_close#}
95299537
9530 {#header_open|Build Mode#}9538 {#header_open|Build Mode#}
lib/docs/main.js+6-2
...@@ -1354,8 +1354,12 @@ const NAV_MODES = {...@@ -1354,8 +1354,12 @@ const NAV_MODES = {
1354 payloadHtml += "ptrCast";1354 payloadHtml += "ptrCast";
1355 break;1355 break;
1356 }1356 }
1357 case "qual_cast": {1357 case "const_cast": {
1358 payloadHtml += "qualCast";1358 payloadHtml += "constCast";
1359 break;
1360 }
1361 case "volatile_cast": {
1362 payloadHtml += "volatileCast";
1359 break;1363 break;
1360 }1364 }
1361 case "truncate": {1365 case "truncate": {
lib/std/child_process.zig+2-2
...@@ -1164,7 +1164,7 @@ fn windowsCreateProcessPathExt(...@@ -1164,7 +1164,7 @@ fn windowsCreateProcessPathExt(
1164 var app_name_unicode_string = windows.UNICODE_STRING{1164 var app_name_unicode_string = windows.UNICODE_STRING{
1165 .Length = app_name_len_bytes,1165 .Length = app_name_len_bytes,
1166 .MaximumLength = app_name_len_bytes,1166 .MaximumLength = app_name_len_bytes,
1167 .Buffer = @qualCast([*:0]u16, app_name_wildcard.ptr),1167 .Buffer = @constCast(app_name_wildcard.ptr),
1168 };1168 };
1169 const rc = windows.ntdll.NtQueryDirectoryFile(1169 const rc = windows.ntdll.NtQueryDirectoryFile(
1170 dir.fd,1170 dir.fd,
...@@ -1261,7 +1261,7 @@ fn windowsCreateProcessPathExt(...@@ -1261,7 +1261,7 @@ fn windowsCreateProcessPathExt(
1261 var app_name_unicode_string = windows.UNICODE_STRING{1261 var app_name_unicode_string = windows.UNICODE_STRING{
1262 .Length = app_name_len_bytes,1262 .Length = app_name_len_bytes,
1263 .MaximumLength = app_name_len_bytes,1263 .MaximumLength = app_name_len_bytes,
1264 .Buffer = @qualCast([*:0]u16, app_name_appended.ptr),1264 .Buffer = @constCast(app_name_appended.ptr),
1265 };1265 };
12661266
1267 // Re-use the directory handle but this time we call with the appended app name1267 // Re-use the directory handle but this time we call with the appended app name
lib/std/fs.zig+1-1
...@@ -1763,7 +1763,7 @@ pub const Dir = struct {...@@ -1763,7 +1763,7 @@ pub const Dir = struct {
1763 var nt_name = w.UNICODE_STRING{1763 var nt_name = w.UNICODE_STRING{
1764 .Length = path_len_bytes,1764 .Length = path_len_bytes,
1765 .MaximumLength = path_len_bytes,1765 .MaximumLength = path_len_bytes,
1766 .Buffer = @qualCast([*:0]u16, sub_path_w),1766 .Buffer = @constCast(sub_path_w),
1767 };1767 };
1768 var attr = w.OBJECT_ATTRIBUTES{1768 var attr = w.OBJECT_ATTRIBUTES{
1769 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),1769 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
lib/std/mem/Allocator.zig+2-2
...@@ -112,7 +112,7 @@ pub fn destroy(self: Allocator, ptr: anytype) void {...@@ -112,7 +112,7 @@ pub fn destroy(self: Allocator, ptr: anytype) void {
112 const info = @typeInfo(@TypeOf(ptr)).Pointer;112 const info = @typeInfo(@TypeOf(ptr)).Pointer;
113 const T = info.child;113 const T = info.child;
114 if (@sizeOf(T) == 0) return;114 if (@sizeOf(T) == 0) return;
115 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(ptr));115 const non_const_ptr = @ptrCast([*]u8, @constCast(ptr));
116 self.rawFree(non_const_ptr[0..@sizeOf(T)], math.log2(info.alignment), @returnAddress());116 self.rawFree(non_const_ptr[0..@sizeOf(T)], math.log2(info.alignment), @returnAddress());
117}117}
118118
...@@ -297,7 +297,7 @@ pub fn free(self: Allocator, memory: anytype) void {...@@ -297,7 +297,7 @@ pub fn free(self: Allocator, memory: anytype) void {
297 const bytes = mem.sliceAsBytes(memory);297 const bytes = mem.sliceAsBytes(memory);
298 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;298 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;
299 if (bytes_len == 0) return;299 if (bytes_len == 0) return;
300 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));300 const non_const_ptr = @constCast(bytes.ptr);
301 // TODO: https://github.com/ziglang/zig/issues/4298301 // TODO: https://github.com/ziglang/zig/issues/4298
302 @memset(non_const_ptr, undefined, bytes_len);302 @memset(non_const_ptr, undefined, bytes_len);
303 self.rawFree(non_const_ptr[0..bytes_len], log2a(Slice.alignment), @returnAddress());303 self.rawFree(non_const_ptr[0..bytes_len], log2a(Slice.alignment), @returnAddress());
lib/std/os.zig+1-1
...@@ -4513,7 +4513,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32...@@ -4513,7 +4513,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32
4513 var nt_name = windows.UNICODE_STRING{4513 var nt_name = windows.UNICODE_STRING{
4514 .Length = path_len_bytes,4514 .Length = path_len_bytes,
4515 .MaximumLength = path_len_bytes,4515 .MaximumLength = path_len_bytes,
4516 .Buffer = @qualCast([*:0]u16, sub_path_w),4516 .Buffer = @constCast(sub_path_w),
4517 };4517 };
4518 var attr = windows.OBJECT_ATTRIBUTES{4518 var attr = windows.OBJECT_ATTRIBUTES{
4519 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),4519 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
lib/std/os/windows.zig+7-7
...@@ -85,7 +85,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN...@@ -85,7 +85,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
85 var nt_name = UNICODE_STRING{85 var nt_name = UNICODE_STRING{
86 .Length = path_len_bytes,86 .Length = path_len_bytes,
87 .MaximumLength = path_len_bytes,87 .MaximumLength = path_len_bytes,
88 .Buffer = @qualCast([*]u16, sub_path_w.ptr),88 .Buffer = @constCast(sub_path_w.ptr),
89 };89 };
90 var attr = OBJECT_ATTRIBUTES{90 var attr = OBJECT_ATTRIBUTES{
91 .Length = @sizeOf(OBJECT_ATTRIBUTES),91 .Length = @sizeOf(OBJECT_ATTRIBUTES),
...@@ -634,7 +634,7 @@ pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void...@@ -634,7 +634,7 @@ pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void
634 var nt_name = UNICODE_STRING{634 var nt_name = UNICODE_STRING{
635 .Length = path_len_bytes,635 .Length = path_len_bytes,
636 .MaximumLength = path_len_bytes,636 .MaximumLength = path_len_bytes,
637 .Buffer = @qualCast([*]u16, path_name.ptr),637 .Buffer = @constCast(path_name.ptr),
638 };638 };
639639
640 const rc = ntdll.RtlSetCurrentDirectory_U(&nt_name);640 const rc = ntdll.RtlSetCurrentDirectory_U(&nt_name);
...@@ -766,7 +766,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin...@@ -766,7 +766,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin
766 var nt_name = UNICODE_STRING{766 var nt_name = UNICODE_STRING{
767 .Length = path_len_bytes,767 .Length = path_len_bytes,
768 .MaximumLength = path_len_bytes,768 .MaximumLength = path_len_bytes,
769 .Buffer = @qualCast([*]u16, sub_path_w.ptr),769 .Buffer = @constCast(sub_path_w.ptr),
770 };770 };
771 var attr = OBJECT_ATTRIBUTES{771 var attr = OBJECT_ATTRIBUTES{
772 .Length = @sizeOf(OBJECT_ATTRIBUTES),772 .Length = @sizeOf(OBJECT_ATTRIBUTES),
...@@ -876,7 +876,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil...@@ -876,7 +876,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
876 .Length = path_len_bytes,876 .Length = path_len_bytes,
877 .MaximumLength = path_len_bytes,877 .MaximumLength = path_len_bytes,
878 // The Windows API makes this mutable, but it will not mutate here.878 // The Windows API makes this mutable, but it will not mutate here.
879 .Buffer = @qualCast([*]u16, sub_path_w.ptr),879 .Buffer = @constCast(sub_path_w.ptr),
880 };880 };
881881
882 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {882 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
...@@ -1414,7 +1414,7 @@ pub fn sendmsg(...@@ -1414,7 +1414,7 @@ pub fn sendmsg(
1414}1414}
14151415
1416pub fn sendto(s: ws2_32.SOCKET, buf: [*]const u8, len: usize, flags: u32, to: ?*const ws2_32.sockaddr, to_len: ws2_32.socklen_t) i32 {1416pub fn sendto(s: ws2_32.SOCKET, buf: [*]const u8, len: usize, flags: u32, to: ?*const ws2_32.sockaddr, to_len: ws2_32.socklen_t) i32 {
1417 var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @qualCast([*]u8, buf) };1417 var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @constCast(buf) };
1418 var bytes_send: DWORD = undefined;1418 var bytes_send: DWORD = undefined;
1419 if (ws2_32.WSASendTo(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_send, flags, to, @intCast(i32, to_len), null, null) == ws2_32.SOCKET_ERROR) {1419 if (ws2_32.WSASendTo(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_send, flags, to, @intCast(i32, to_len), null, null) == ws2_32.SOCKET_ERROR) {
1420 return ws2_32.SOCKET_ERROR;1420 return ws2_32.SOCKET_ERROR;
...@@ -1876,13 +1876,13 @@ pub fn eqlIgnoreCaseWTF16(a: []const u16, b: []const u16) bool {...@@ -1876,13 +1876,13 @@ pub fn eqlIgnoreCaseWTF16(a: []const u16, b: []const u16) bool {
1876 const a_string = UNICODE_STRING{1876 const a_string = UNICODE_STRING{
1877 .Length = a_bytes,1877 .Length = a_bytes,
1878 .MaximumLength = a_bytes,1878 .MaximumLength = a_bytes,
1879 .Buffer = @qualCast([*]u16, a.ptr),1879 .Buffer = @constCast(a.ptr),
1880 };1880 };
1881 const b_bytes = @intCast(u16, b.len * 2);1881 const b_bytes = @intCast(u16, b.len * 2);
1882 const b_string = UNICODE_STRING{1882 const b_string = UNICODE_STRING{
1883 .Length = b_bytes,1883 .Length = b_bytes,
1884 .MaximumLength = b_bytes,1884 .MaximumLength = b_bytes,
1885 .Buffer = @qualCast([*]u16, b.ptr),1885 .Buffer = @constCast(b.ptr),
1886 };1886 };
1887 return ntdll.RtlEqualUnicodeString(&a_string, &b_string, TRUE) == TRUE;1887 return ntdll.RtlEqualUnicodeString(&a_string, &b_string, TRUE) == TRUE;
1888}1888}
lib/std/zig/c_translation.zig+4-2
...@@ -74,8 +74,10 @@ fn castPtr(comptime DestType: type, target: anytype) DestType {...@@ -74,8 +74,10 @@ fn castPtr(comptime DestType: type, target: anytype) DestType {
74 const dest = ptrInfo(DestType);74 const dest = ptrInfo(DestType);
75 const source = ptrInfo(@TypeOf(target));75 const source = ptrInfo(@TypeOf(target));
7676
77 if (source.is_const and !dest.is_const or source.is_volatile and !dest.is_volatile)77 if (source.is_const and !dest.is_const)
78 return @qualCast(DestType, target)78 return @constCast(target)
79 else if (source.is_volatile and !dest.is_volatile)
80 return @volatileCast(target)
79 else if (@typeInfo(dest.child) == .Opaque)81 else if (@typeInfo(dest.child) == .Opaque)
80 // dest.alignment would error out82 // dest.alignment would error out
81 return @ptrCast(DestType, target)83 return @ptrCast(DestType, target)
src/AstGen.zig+16-2
...@@ -2531,7 +2531,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2531,7 +2531,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2531 .bit_size_of,2531 .bit_size_of,
2532 .typeof_log2_int_type,2532 .typeof_log2_int_type,
2533 .ptr_to_int,2533 .ptr_to_int,
2534 .qual_cast,
2535 .align_of,2534 .align_of,
2536 .bool_to_int,2535 .bool_to_int,
2537 .embed_file,2536 .embed_file,
...@@ -8039,7 +8038,6 @@ fn builtinCall(...@@ -8039,7 +8038,6 @@ fn builtinCall(
8039 .float_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast),8038 .float_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast),
8040 .int_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast),8039 .int_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast),
8041 .ptr_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast),8040 .ptr_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast),
8042 .qual_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .qual_cast),
8043 .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate),8041 .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate),
8044 // zig fmt: on8042 // zig fmt: on
80458043
...@@ -8115,6 +8113,22 @@ fn builtinCall(...@@ -8115,6 +8113,22 @@ fn builtinCall(
8115 });8113 });
8116 return rvalue(gz, ri, result, node);8114 return rvalue(gz, ri, result, node);
8117 },8115 },
8116 .const_cast => {
8117 const operand = try expr(gz, scope, .{ .rl = .none }, params[0]);
8118 const result = try gz.addExtendedPayload(.const_cast, Zir.Inst.UnNode{
8119 .node = gz.nodeIndexToRelative(node),
8120 .operand = operand,
8121 });
8122 return rvalue(gz, ri, result, node);
8123 },
8124 .volatile_cast => {
8125 const operand = try expr(gz, scope, .{ .rl = .none }, params[0]);
8126 const result = try gz.addExtendedPayload(.volatile_cast, Zir.Inst.UnNode{
8127 .node = gz.nodeIndexToRelative(node),
8128 .operand = operand,
8129 });
8130 return rvalue(gz, ri, result, node);
8131 },
81188132
8119 // zig fmt: off8133 // zig fmt: off
8120 .has_decl => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_decl),8134 .has_decl => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_decl),
src/Autodoc.zig+2-1
...@@ -1400,7 +1400,6 @@ fn walkInstruction(...@@ -1400,7 +1400,6 @@ fn walkInstruction(
1400 .float_cast,1400 .float_cast,
1401 .int_cast,1401 .int_cast,
1402 .ptr_cast,1402 .ptr_cast,
1403 .qual_cast,
1404 .truncate,1403 .truncate,
1405 .align_cast,1404 .align_cast,
1406 .has_decl,1405 .has_decl,
...@@ -2983,6 +2982,8 @@ fn walkInstruction(...@@ -2983,6 +2982,8 @@ fn walkInstruction(
2983 .error_to_int,2982 .error_to_int,
2984 .int_to_error,2983 .int_to_error,
2985 .reify,2984 .reify,
2985 .const_cast,
2986 .volatile_cast,
2986 => {2987 => {
2987 const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data;2988 const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data;
2988 const bin_index = self.exprs.items.len;2989 const bin_index = self.exprs.items.len;
src/BuiltinFn.zig+16-8
...@@ -28,6 +28,7 @@ pub const Tag = enum {...@@ -28,6 +28,7 @@ pub const Tag = enum {
28 cmpxchg_weak,28 cmpxchg_weak,
29 compile_error,29 compile_error,
30 compile_log,30 compile_log,
31 const_cast,
31 ctz,32 ctz,
32 c_undef,33 c_undef,
33 c_va_arg,34 c_va_arg,
...@@ -75,7 +76,6 @@ pub const Tag = enum {...@@ -75,7 +76,6 @@ pub const Tag = enum {
75 prefetch,76 prefetch,
76 ptr_cast,77 ptr_cast,
77 ptr_to_int,78 ptr_to_int,
78 qual_cast,
79 rem,79 rem,
80 return_address,80 return_address,
81 select,81 select,
...@@ -116,6 +116,7 @@ pub const Tag = enum {...@@ -116,6 +116,7 @@ pub const Tag = enum {
116 TypeOf,116 TypeOf,
117 union_init,117 union_init,
118 Vector,118 Vector,
119 volatile_cast,
119};120};
120121
121pub const MemLocRequirement = enum {122pub const MemLocRequirement = enum {
...@@ -345,6 +346,13 @@ pub const list = list: {...@@ -345,6 +346,13 @@ pub const list = list: {
345 .param_count = null,346 .param_count = null,
346 },347 },
347 },348 },
349 .{
350 "@constCast",
351 .{
352 .tag = .const_cast,
353 .param_count = 1,
354 },
355 },
348 .{356 .{
349 "@ctz",357 "@ctz",
350 .{358 .{
...@@ -675,13 +683,6 @@ pub const list = list: {...@@ -675,13 +683,6 @@ pub const list = list: {
675 .param_count = 1,683 .param_count = 1,
676 },684 },
677 },685 },
678 .{
679 "@qualCast",
680 .{
681 .tag = .qual_cast,
682 .param_count = 2,
683 },
684 },
685 .{686 .{
686 "@rem",687 "@rem",
687 .{688 .{
...@@ -964,5 +965,12 @@ pub const list = list: {...@@ -964,5 +965,12 @@ pub const list = list: {
964 .param_count = 2,965 .param_count = 2,
965 },966 },
966 },967 },
968 .{
969 "@volatileCast",
970 .{
971 .tag = .volatile_cast,
972 .param_count = 1,
973 },
974 },
967 });975 });
968};976};
src/Sema.zig+29-31
...@@ -1015,7 +1015,6 @@ fn analyzeBodyInner(...@@ -1015,7 +1015,6 @@ fn analyzeBodyInner(
1015 .float_cast => try sema.zirFloatCast(block, inst),1015 .float_cast => try sema.zirFloatCast(block, inst),
1016 .int_cast => try sema.zirIntCast(block, inst),1016 .int_cast => try sema.zirIntCast(block, inst),
1017 .ptr_cast => try sema.zirPtrCast(block, inst),1017 .ptr_cast => try sema.zirPtrCast(block, inst),
1018 .qual_cast => try sema.zirQualCast(block, inst),
1019 .truncate => try sema.zirTruncate(block, inst),1018 .truncate => try sema.zirTruncate(block, inst),
1020 .align_cast => try sema.zirAlignCast(block, inst),1019 .align_cast => try sema.zirAlignCast(block, inst),
1021 .has_decl => try sema.zirHasDecl(block, inst),1020 .has_decl => try sema.zirHasDecl(block, inst),
...@@ -1147,6 +1146,8 @@ fn analyzeBodyInner(...@@ -1147,6 +1146,8 @@ fn analyzeBodyInner(
1147 .c_va_copy => try sema.zirCVaCopy( block, extended),1146 .c_va_copy => try sema.zirCVaCopy( block, extended),
1148 .c_va_end => try sema.zirCVaEnd( block, extended),1147 .c_va_end => try sema.zirCVaEnd( block, extended),
1149 .c_va_start => try sema.zirCVaStart( block, extended),1148 .c_va_start => try sema.zirCVaStart( block, extended),
1149 .const_cast, => try sema.zirConstCast( block, extended),
1150 .volatile_cast, => try sema.zirVolatileCast( block, extended),
1150 // zig fmt: on1151 // zig fmt: on
11511152
1152 .fence => {1153 .fence => {
...@@ -19545,7 +19546,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19545,7 +19546,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19545 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});19546 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});
19546 errdefer msg.destroy(sema.gpa);19547 errdefer msg.destroy(sema.gpa);
1954719548
19548 try sema.errNote(block, src, msg, "consider using '@qualCast'", .{});19549 try sema.errNote(block, src, msg, "consider using '@constCast'", .{});
19549 break :msg msg;19550 break :msg msg;
19550 };19551 };
19551 return sema.failWithOwnedErrorMsg(msg);19552 return sema.failWithOwnedErrorMsg(msg);
...@@ -19555,7 +19556,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19555,7 +19556,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19555 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});19556 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});
19556 errdefer msg.destroy(sema.gpa);19557 errdefer msg.destroy(sema.gpa);
1955719558
19558 try sema.errNote(block, src, msg, "consider using '@qualCast'", .{});19559 try sema.errNote(block, src, msg, "consider using '@volatileCast'", .{});
19559 break :msg msg;19560 break :msg msg;
19560 };19561 };
19561 return sema.failWithOwnedErrorMsg(msg);19562 return sema.failWithOwnedErrorMsg(msg);
...@@ -19660,40 +19661,37 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19660,40 +19661,37 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19660 return block.addBitCast(aligned_dest_ty, ptr);19661 return block.addBitCast(aligned_dest_ty, ptr);
19661}19662}
1966219663
19663fn zirQualCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19664fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
19664 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;19665 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
19665 const src = inst_data.src();19666 const src = LazySrcLoc.nodeOffset(extra.node);
19666 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };19667 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
19667 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };19668 const operand = try sema.resolveInst(extra.operand);
19668 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
19669 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
19670 const operand = try sema.resolveInst(extra.rhs);
19671 const operand_ty = sema.typeOf(operand);19669 const operand_ty = sema.typeOf(operand);
19672
19673 try sema.checkPtrType(block, dest_ty_src, dest_ty);
19674 try sema.checkPtrOperand(block, operand_src, operand_ty);19670 try sema.checkPtrOperand(block, operand_src, operand_ty);
1967519671
19676 var operand_payload = operand_ty.ptrInfo();19672 var ptr_info = operand_ty.ptrInfo().data;
19677 var dest_info = dest_ty.ptrInfo();19673 ptr_info.mutable = true;
19674 const dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
19675
19676 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
19677 return sema.addConstant(dest_ty, operand_val);
19678 }
1967819679
19679 operand_payload.data.mutable = dest_info.data.mutable;19680 try sema.requireRuntimeBlock(block, src, null);
19680 operand_payload.data.@"volatile" = dest_info.data.@"volatile";19681 return block.addBitCast(dest_ty, operand);
19682}
1968119683
19682 const altered_operand_ty = Type.initPayload(&operand_payload.base);19684fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
19683 if (!altered_operand_ty.eql(dest_ty, sema.mod)) {19685 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
19684 const msg = msg: {19686 const src = LazySrcLoc.nodeOffset(extra.node);
19685 const msg = try sema.errMsg(block, src, "'@qualCast' can only modify 'const' and 'volatile' qualifiers", .{});19687 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
19686 errdefer msg.destroy(sema.gpa);19688 const operand = try sema.resolveInst(extra.operand);
19689 const operand_ty = sema.typeOf(operand);
19690 try sema.checkPtrOperand(block, operand_src, operand_ty);
1968719691
19688 dest_info.data.mutable = !operand_ty.isConstPtr();19692 var ptr_info = operand_ty.ptrInfo().data;
19689 dest_info.data.@"volatile" = operand_ty.isVolatilePtr();19693 ptr_info.@"volatile" = false;
19690 const altered_dest_ty = Type.initPayload(&dest_info.base);19694 const dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
19691 try sema.errNote(block, src, msg, "expected type '{}'", .{altered_dest_ty.fmt(sema.mod)});
19692 try sema.errNote(block, src, msg, "got type '{}'", .{operand_ty.fmt(sema.mod)});
19693 break :msg msg;
19694 };
19695 return sema.failWithOwnedErrorMsg(msg);
19696 }
1969719695
19698 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {19696 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
19699 return sema.addConstant(dest_ty, operand_val);19697 return sema.addConstant(dest_ty, operand_val);
src/Zir.zig+6-6
...@@ -857,9 +857,6 @@ pub const Inst = struct {...@@ -857,9 +857,6 @@ pub const Inst = struct {
857 /// Implements the `@ptrCast` builtin.857 /// Implements the `@ptrCast` builtin.
858 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.858 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
859 ptr_cast,859 ptr_cast,
860 /// Implements the `@qualCast` builtin.
861 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
862 qual_cast,
863 /// Implements the `@truncate` builtin.860 /// Implements the `@truncate` builtin.
864 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.861 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
865 truncate,862 truncate,
...@@ -1198,7 +1195,6 @@ pub const Inst = struct {...@@ -1198,7 +1195,6 @@ pub const Inst = struct {
1198 .float_cast,1195 .float_cast,
1199 .int_cast,1196 .int_cast,
1200 .ptr_cast,1197 .ptr_cast,
1201 .qual_cast,
1202 .truncate,1198 .truncate,
1203 .align_cast,1199 .align_cast,
1204 .has_field,1200 .has_field,
...@@ -1488,7 +1484,6 @@ pub const Inst = struct {...@@ -1488,7 +1484,6 @@ pub const Inst = struct {
1488 .float_cast,1484 .float_cast,
1489 .int_cast,1485 .int_cast,
1490 .ptr_cast,1486 .ptr_cast,
1491 .qual_cast,
1492 .truncate,1487 .truncate,
1493 .align_cast,1488 .align_cast,
1494 .has_field,1489 .has_field,
...@@ -1760,7 +1755,6 @@ pub const Inst = struct {...@@ -1760,7 +1755,6 @@ pub const Inst = struct {
1760 .float_cast = .pl_node,1755 .float_cast = .pl_node,
1761 .int_cast = .pl_node,1756 .int_cast = .pl_node,
1762 .ptr_cast = .pl_node,1757 .ptr_cast = .pl_node,
1763 .qual_cast = .pl_node,
1764 .truncate = .pl_node,1758 .truncate = .pl_node,
1765 .align_cast = .pl_node,1759 .align_cast = .pl_node,
1766 .typeof_builtin = .pl_node,1760 .typeof_builtin = .pl_node,
...@@ -2004,6 +1998,12 @@ pub const Inst = struct {...@@ -2004,6 +1998,12 @@ pub const Inst = struct {
2004 /// Implement builtin `@cVaStart`.1998 /// Implement builtin `@cVaStart`.
2005 /// `operand` is `src_node: i32`.1999 /// `operand` is `src_node: i32`.
2006 c_va_start,2000 c_va_start,
2001 /// Implements the `@constCast` builtin.
2002 /// `operand` is payload index to `UnNode`.
2003 const_cast,
2004 /// Implements the `@volatileCast` builtin.
2005 /// `operand` is payload index to `UnNode`.
2006 volatile_cast,
20072007
2008 pub const InstData = struct {2008 pub const InstData = struct {
2009 opcode: Extended,2009 opcode: Extended,
src/print_zir.zig+2-1
...@@ -332,7 +332,6 @@ const Writer = struct {...@@ -332,7 +332,6 @@ const Writer = struct {
332 .float_cast,332 .float_cast,
333 .int_cast,333 .int_cast,
334 .ptr_cast,334 .ptr_cast,
335 .qual_cast,
336 .truncate,335 .truncate,
337 .align_cast,336 .align_cast,
338 .div_exact,337 .div_exact,
...@@ -507,6 +506,8 @@ const Writer = struct {...@@ -507,6 +506,8 @@ const Writer = struct {
507 .reify,506 .reify,
508 .c_va_copy,507 .c_va_copy,
509 .c_va_end,508 .c_va_end,
509 .const_cast,
510 .volatile_cast,
510 => {511 => {
511 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;512 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
512 const src = LazySrcLoc.nodeOffset(inst_data.node);513 const src = LazySrcLoc.nodeOffset(inst_data.node);
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior/cast.zig+15
...@@ -1553,3 +1553,18 @@ test "peer type resolution forms error union" {...@@ -1553,3 +1553,18 @@ test "peer type resolution forms error union" {
1553 } else @intCast(u32, foo);1553 } else @intCast(u32, foo);
1554 try expect(try result == 123);1554 try expect(try result == 123);
1555}1555}
1556
1557test "@constCast without a result location" {
1558 const x: i32 = 1234;
1559 const y = @constCast(&x);
1560 try expect(@TypeOf(y) == *i32);
1561 try expect(y.* == 1234);
1562}
1563
1564test "@volatileCast without a result location" {
1565 var x: i32 = 1234;
1566 var y: *volatile i32 = &x;
1567 const z = @volatileCast(y);
1568 try expect(@TypeOf(z) == *i32);
1569 try expect(z.* == 1234);
1570}
test/cases/compile_errors/invalid_qualcast.zig deleted-12
...@@ -1,12 +0,0 @@
1pub export fn entry() void {
2 var a: [*:0]const volatile u16 = undefined;
3 _ = @qualCast([*]u16, a);
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :3:9: error: '@qualCast' can only modify 'const' and 'volatile' qualifiers
11// :3:9: note: expected type '[*]const volatile u16'
12// :3:9: note: got type '[*:0]const volatile u16'
test/cases/compile_errors/ptrCast_discards_const_qualifier.zig+1-1
...@@ -9,4 +9,4 @@ export fn entry() void {...@@ -9,4 +9,4 @@ export fn entry() void {
9// target=native9// target=native
10//10//
11// :3:15: error: cast discards const qualifier11// :3:15: error: cast discards const qualifier
12// :3:15: note: consider using '@qualCast'12// :3:15: note: consider using '@constCast'