Commit d7314555f2
Changed files (6)
test
lib/std/meta.zig
@@ -302,7 +302,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.Array = .{
.len = array_info.len,
.child = array_info.child,
- .sentinel = &sentinel_val,
+ .sentinel = @ptrCast(?*const anyopaque, &sentinel_val),
},
}),
.is_allowzero = info.is_allowzero,
@@ -320,7 +320,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.address_space = info.address_space,
.child = info.child,
.is_allowzero = info.is_allowzero,
- .sentinel = &sentinel_val,
+ .sentinel = @ptrCast(?*const anyopaque, &sentinel_val),
},
}),
else => {},
@@ -338,7 +338,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.address_space = ptr_info.address_space,
.child = ptr_info.child,
.is_allowzero = ptr_info.is_allowzero,
- .sentinel = &sentinel_val,
+ .sentinel = @ptrCast(?*const anyopaque, &sentinel_val),
},
}),
},
lib/std/start_windows_tls.zig
@@ -42,7 +42,7 @@ export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY{
.StartAddressOfRawData = &_tls_start,
.EndAddressOfRawData = &_tls_end,
.AddressOfIndex = &_tls_index,
- .AddressOfCallBacks = &__xl_a,
+ .AddressOfCallBacks = @ptrCast(*anyopaque, &__xl_a),
.SizeOfZeroFill = 0,
.Characteristics = 0,
};
src/Sema.zig
@@ -23928,9 +23928,20 @@ fn coerceExtra(
// cast from ?*T and ?[*]T to ?*anyopaque
// but don't do it if the source type is a double pointer
if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and
- inst_ty.isPtrLikeOptional() and inst_ty.elemType2().zigTypeTag() != .Pointer)
- {
+ inst_ty.isPtrAtRuntime())
+ anyopaque_check: {
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
+ const elem_ty = inst_ty.elemType2();
+ if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {
+ in_memory_result = .{ .double_ptr_to_anyopaque = .{
+ .actual = inst_ty,
+ .wanted = dest_ty,
+ } };
+ break :optional;
+ }
+ // Let the logic below handle wrapping the optional now that
+ // it has been checked to correctly coerce.
+ if (!inst_ty.isPtrLikeOptional()) break: anyopaque_check;
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
}
@@ -24053,9 +24064,16 @@ fn coerceExtra(
// cast from *T and [*]T to *anyopaque
// but don't do it if the source type is a double pointer
- if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and
- inst_ty.childType().zigTypeTag() != .Pointer and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
- {
+ if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer) {
+ if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
+ const elem_ty = inst_ty.elemType2();
+ if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {
+ in_memory_result = .{ .double_ptr_to_anyopaque = .{
+ .actual = inst_ty,
+ .wanted = dest_ty,
+ } };
+ break :pointer;
+ }
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
}
@@ -24537,6 +24555,7 @@ const InMemoryCoercionResult = union(enum) {
ptr_allowzero: Pair,
ptr_bit_range: BitRange,
ptr_alignment: IntPair,
+ double_ptr_to_anyopaque: Pair,
const Pair = struct {
actual: Type,
@@ -24829,6 +24848,12 @@ const InMemoryCoercionResult = union(enum) {
});
break;
},
+ .double_ptr_to_anyopaque => |pair| {
+ try sema.errNote(block, src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
+ pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
+ });
+ break;
+ },
};
}
};
src/type.zig
@@ -3941,10 +3941,7 @@ pub const Type = extern union {
.optional => {
var buf: Payload.ElemType = undefined;
const child_type = self.optionalChild(&buf);
- // optionals of zero sized pointers behave like bools
- if (!child_type.hasRuntimeBits()) return false;
if (child_type.zigTypeTag() != .Pointer) return false;
-
const info = child_type.ptrInfo().data;
switch (info.size) {
.Slice, .C => return false,
test/cases/compile_errors/dont_implicit_cast_double_pointer_to_anyopaque.zig
@@ -1,14 +0,0 @@
-export fn entry() void {
- var a: u32 = 1;
- var ptr: *align(@alignOf(u32)) anyopaque = &a;
- var b: *u32 = @ptrCast(*u32, ptr);
- var ptr2: *anyopaque = &b;
- _ = ptr2;
-}
-
-// error
-// backend=stage2
-// target=native
-//
-// :5:28: error: expected type '*anyopaque', found '**u32'
-// :5:28: note: pointer type child '*u32' cannot cast into pointer type child 'anyopaque'
test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig
@@ -0,0 +1,28 @@
+pub export fn entry1() void {
+ const x: usize = 5;
+
+ const ptr: *const anyopaque = &(&x);
+ _ = ptr;
+}
+pub export fn entry2() void {
+ var val: [*:0]u8 = undefined;
+ func(&val);
+}
+fn func(_: ?*anyopaque) void {}
+pub export fn entry3() void {
+ var x: *?*usize = undefined;
+
+ const ptr: *const anyopaque = x;
+ _ = ptr;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :4:35: error: expected type '*const anyopaque', found '*const *const usize'
+// :4:35: note: cannot implicitly cast double pointer '*const *const usize' to anyopaque pointer '*const anyopaque'
+// :9:10: error: expected type '?*anyopaque', found '*[*:0]u8'
+// :9:10: note: cannot implicitly cast double pointer '*[*:0]u8' to anyopaque pointer '?*anyopaque'
+// :15:35: error: expected type '*const anyopaque', found '*?*usize'
+// :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque'