Skip to content

Commit 6b7ad22

Browse files
authored
Merge pull request #14477 from Vexu/fixes
Improve `@ptrCast` errors, fix some bugs
2 parents e712d5f + 629c310 commit 6b7ad22

30 files changed

+280
-36
lines changed

doc/langref.html.in

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8809,6 +8809,15 @@ pub const PrefetchOptions = struct {
88098809
{#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
88108810
to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.
88118811
</p>
8812+
<p>
8813+
{#syntax#}@ptrCast{#endsyntax#} cannot be used for:
8814+
</p>
8815+
<ul>
8816+
<li>Removing {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier, use {#link|@qualCast#}.</li>
8817+
<li>Changing pointer address space, use {#link|@addrSpaceCast#}.</li>
8818+
<li>Increasing pointer alignment, use {#link|@alignCast#}.</li>
8819+
<li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}.</li>
8820+
</ul>
88128821
{#header_close#}
88138822

88148823
{#header_open|@ptrToInt#}
@@ -8821,6 +8830,13 @@ pub const PrefetchOptions = struct {
88218830

88228831
{#header_close#}
88238832

8833+
{#header_open|@qualCast#}
8834+
<pre>{#syntax#}@qualCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre>
8835+
<p>
8836+
Remove {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier from a pointer.
8837+
</p>
8838+
{#header_close#}
8839+
88248840
{#header_open|@rem#}
88258841
<pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>
88268842
<p>

lib/std/child_process.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ fn windowsCreateProcessPathExt(
11641164
var app_name_unicode_string = windows.UNICODE_STRING{
11651165
.Length = app_name_len_bytes,
11661166
.MaximumLength = app_name_len_bytes,
1167-
.Buffer = @intToPtr([*]u16, @ptrToInt(app_name_wildcard.ptr)),
1167+
.Buffer = @qualCast([*:0]u16, app_name_wildcard.ptr),
11681168
};
11691169
const rc = windows.ntdll.NtQueryDirectoryFile(
11701170
dir.fd,
@@ -1261,7 +1261,7 @@ fn windowsCreateProcessPathExt(
12611261
var app_name_unicode_string = windows.UNICODE_STRING{
12621262
.Length = app_name_len_bytes,
12631263
.MaximumLength = app_name_len_bytes,
1264-
.Buffer = @intToPtr([*]u16, @ptrToInt(app_name_appended.ptr)),
1264+
.Buffer = @qualCast([*:0]u16, app_name_appended.ptr),
12651265
};
12661266

12671267
// Re-use the directory handle but this time we call with the appended app name

lib/std/fs.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1763,7 +1763,7 @@ pub const Dir = struct {
17631763
var nt_name = w.UNICODE_STRING{
17641764
.Length = path_len_bytes,
17651765
.MaximumLength = path_len_bytes,
1766-
.Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)),
1766+
.Buffer = @qualCast([*:0]u16, sub_path_w),
17671767
};
17681768
var attr = w.OBJECT_ATTRIBUTES{
17691769
.Length = @sizeOf(w.OBJECT_ATTRIBUTES),

lib/std/os.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4513,7 +4513,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32
45134513
var nt_name = windows.UNICODE_STRING{
45144514
.Length = path_len_bytes,
45154515
.MaximumLength = path_len_bytes,
4516-
.Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)),
4516+
.Buffer = @qualCast([*:0]u16, sub_path_w),
45174517
};
45184518
var attr = windows.OBJECT_ATTRIBUTES{
45194519
.Length = @sizeOf(windows.OBJECT_ATTRIBUTES),

lib/std/os/windows.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
8585
var nt_name = UNICODE_STRING{
8686
.Length = path_len_bytes,
8787
.MaximumLength = path_len_bytes,
88-
.Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w.ptr)),
88+
.Buffer = @qualCast([*]u16, sub_path_w.ptr),
8989
};
9090
var attr = OBJECT_ATTRIBUTES{
9191
.Length = @sizeOf(OBJECT_ATTRIBUTES),
@@ -634,7 +634,7 @@ pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void
634634
var nt_name = UNICODE_STRING{
635635
.Length = path_len_bytes,
636636
.MaximumLength = path_len_bytes,
637-
.Buffer = @intToPtr([*]u16, @ptrToInt(path_name.ptr)),
637+
.Buffer = @qualCast([*]u16, path_name.ptr),
638638
};
639639

640640
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
766766
var nt_name = UNICODE_STRING{
767767
.Length = path_len_bytes,
768768
.MaximumLength = path_len_bytes,
769-
.Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w.ptr)),
769+
.Buffer = @qualCast([*]u16, sub_path_w.ptr),
770770
};
771771
var attr = OBJECT_ATTRIBUTES{
772772
.Length = @sizeOf(OBJECT_ATTRIBUTES),
@@ -876,7 +876,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
876876
.Length = path_len_bytes,
877877
.MaximumLength = path_len_bytes,
878878
// The Windows API makes this mutable, but it will not mutate here.
879-
.Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w.ptr)),
879+
.Buffer = @qualCast([*]u16, sub_path_w.ptr),
880880
};
881881

882882
if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
@@ -1414,7 +1414,7 @@ pub fn sendmsg(
14141414
}
14151415

14161416
pub 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 = @intToPtr([*]u8, @ptrToInt(buf)) };
1417+
var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @qualCast([*]u8, buf) };
14181418
var bytes_send: DWORD = undefined;
14191419
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) {
14201420
return ws2_32.SOCKET_ERROR;
@@ -1876,13 +1876,13 @@ pub fn eqlIgnoreCaseWTF16(a: []const u16, b: []const u16) bool {
18761876
const a_string = UNICODE_STRING{
18771877
.Length = a_bytes,
18781878
.MaximumLength = a_bytes,
1879-
.Buffer = @intToPtr([*]u16, @ptrToInt(a.ptr)),
1879+
.Buffer = @qualCast([*]u16, a.ptr),
18801880
};
18811881
const b_bytes = @intCast(u16, b.len * 2);
18821882
const b_string = UNICODE_STRING{
18831883
.Length = b_bytes,
18841884
.MaximumLength = b_bytes,
1885-
.Buffer = @intToPtr([*]u16, @ptrToInt(b.ptr)),
1885+
.Buffer = @qualCast([*]u16, b.ptr),
18861886
};
18871887
return ntdll.RtlEqualUnicodeString(&a_string, &b_string, TRUE) == TRUE;
18881888
}

lib/std/zig/c_translation.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn castPtr(comptime DestType: type, target: anytype) DestType {
7575
const source = ptrInfo(@TypeOf(target));
7676

7777
if (source.is_const and !dest.is_const or source.is_volatile and !dest.is_volatile)
78-
return @intToPtr(DestType, @ptrToInt(target))
78+
return @qualCast(DestType, target)
7979
else if (@typeInfo(dest.child) == .Opaque)
8080
// dest.alignment would error out
8181
return @ptrCast(DestType, target)

src/AstGen.zig

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,6 +2530,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
25302530
.bit_size_of,
25312531
.typeof_log2_int_type,
25322532
.ptr_to_int,
2533+
.qual_cast,
25332534
.align_of,
25342535
.bool_to_int,
25352536
.embed_file,
@@ -4278,7 +4279,34 @@ fn testDecl(
42784279
var num_namespaces_out: u32 = 0;
42794280
var capturing_namespace: ?*Scope.Namespace = null;
42804281
while (true) switch (s.tag) {
4281-
.local_val, .local_ptr => unreachable, // a test cannot be in a local scope
4282+
.local_val => {
4283+
const local_val = s.cast(Scope.LocalVal).?;
4284+
if (local_val.name == name_str_index) {
4285+
local_val.used = test_name_token;
4286+
return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{
4287+
@tagName(local_val.id_cat),
4288+
}, &[_]u32{
4289+
try astgen.errNoteTok(local_val.token_src, "{s} declared here", .{
4290+
@tagName(local_val.id_cat),
4291+
}),
4292+
});
4293+
}
4294+
s = local_val.parent;
4295+
},
4296+
.local_ptr => {
4297+
const local_ptr = s.cast(Scope.LocalPtr).?;
4298+
if (local_ptr.name == name_str_index) {
4299+
local_ptr.used = test_name_token;
4300+
return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{
4301+
@tagName(local_ptr.id_cat),
4302+
}, &[_]u32{
4303+
try astgen.errNoteTok(local_ptr.token_src, "{s} declared here", .{
4304+
@tagName(local_ptr.id_cat),
4305+
}),
4306+
});
4307+
}
4308+
s = local_ptr.parent;
4309+
},
42824310
.gen_zir => s = s.cast(GenZir).?.parent,
42834311
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
42844312
.namespace, .enum_namespace => {
@@ -8010,6 +8038,7 @@ fn builtinCall(
80108038
.float_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast),
80118039
.int_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast),
80128040
.ptr_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast),
8041+
.qual_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .qual_cast),
80138042
.truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate),
80148043
// zig fmt: on
80158044

@@ -8692,6 +8721,7 @@ fn callExpr(
86928721
defer arg_block.unstack();
86938722

86948723
// `call_inst` is reused to provide the param type.
8724+
arg_block.rl_ty_inst = call_inst;
86958725
const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);
86968726
_ = try arg_block.addBreak(.break_inline, call_index, arg_ref);
86978727

@@ -10840,7 +10870,12 @@ const GenZir = struct {
1084010870
// we emit ZIR for the block break instructions to have the result values,
1084110871
// and then rvalue() on that to pass the value to the result location.
1084210872
switch (parent_ri.rl) {
10843-
.ty, .coerced_ty => |ty_inst| {
10873+
.coerced_ty => |ty_inst| {
10874+
// Type coercion needs to happend before breaks.
10875+
gz.rl_ty_inst = ty_inst;
10876+
gz.break_result_info = .{ .rl = .{ .ty = ty_inst } };
10877+
},
10878+
.ty => |ty_inst| {
1084410879
gz.rl_ty_inst = ty_inst;
1084510880
gz.break_result_info = parent_ri;
1084610881
},

src/BuiltinFn.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub const Tag = enum {
7575
prefetch,
7676
ptr_cast,
7777
ptr_to_int,
78+
qual_cast,
7879
rem,
7980
return_address,
8081
select,
@@ -674,6 +675,13 @@ pub const list = list: {
674675
.param_count = 1,
675676
},
676677
},
678+
.{
679+
"@qualCast",
680+
.{
681+
.tag = .qual_cast,
682+
.param_count = 2,
683+
},
684+
},
677685
.{
678686
"@rem",
679687
.{

0 commit comments

Comments
 (0)