| author | |
| committer | |
| log | d7314555f2bc413494d58bbafa2d607b88922afb |
| tree | dab26956d951366fdd37024781392428decf6c80 |
| parent | 9607bd90e6927eea0fc7d57e042d03657afbf70d |
Closes #120426 files changed, 62 insertions(+), 26 deletions(-)
lib/std/meta.zig+3-3| ... | @@ -302,7 +302,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { | ... | @@ -302,7 +302,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { |
| 302 | .Array = .{ | 302 | .Array = .{ |
| 303 | .len = array_info.len, | 303 | .len = array_info.len, |
| 304 | .child = array_info.child, | 304 | .child = array_info.child, |
| 305 | .sentinel = &sentinel_val, | 305 | .sentinel = @ptrCast(?*const anyopaque, &sentinel_val), |
| 306 | }, | 306 | }, |
| 307 | }), | 307 | }), |
| 308 | .is_allowzero = info.is_allowzero, | 308 | .is_allowzero = info.is_allowzero, |
| ... | @@ -320,7 +320,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { | ... | @@ -320,7 +320,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { |
| 320 | .address_space = info.address_space, | 320 | .address_space = info.address_space, |
| 321 | .child = info.child, | 321 | .child = info.child, |
| 322 | .is_allowzero = info.is_allowzero, | 322 | .is_allowzero = info.is_allowzero, |
| 323 | .sentinel = &sentinel_val, | 323 | .sentinel = @ptrCast(?*const anyopaque, &sentinel_val), |
| 324 | }, | 324 | }, |
| 325 | }), | 325 | }), |
| 326 | else => {}, | 326 | else => {}, |
| ... | @@ -338,7 +338,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { | ... | @@ -338,7 +338,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { |
| 338 | .address_space = ptr_info.address_space, | 338 | .address_space = ptr_info.address_space, |
| 339 | .child = ptr_info.child, | 339 | .child = ptr_info.child, |
| 340 | .is_allowzero = ptr_info.is_allowzero, | 340 | .is_allowzero = ptr_info.is_allowzero, |
| 341 | .sentinel = &sentinel_val, | 341 | .sentinel = @ptrCast(?*const anyopaque, &sentinel_val), |
| 342 | }, | 342 | }, |
| 343 | }), | 343 | }), |
| 344 | }, | 344 | }, |
lib/std/start_windows_tls.zig+1-1| ... | @@ -42,7 +42,7 @@ export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY{ | ... | @@ -42,7 +42,7 @@ export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY{ |
| 42 | .StartAddressOfRawData = &_tls_start, | 42 | .StartAddressOfRawData = &_tls_start, |
| 43 | .EndAddressOfRawData = &_tls_end, | 43 | .EndAddressOfRawData = &_tls_end, |
| 44 | .AddressOfIndex = &_tls_index, | 44 | .AddressOfIndex = &_tls_index, |
| 45 | .AddressOfCallBacks = &__xl_a, | 45 | .AddressOfCallBacks = @ptrCast(*anyopaque, &__xl_a), |
| 46 | .SizeOfZeroFill = 0, | 46 | .SizeOfZeroFill = 0, |
| 47 | .Characteristics = 0, | 47 | .Characteristics = 0, |
| 48 | }; | 48 | }; |
src/Sema.zig+30-5| ... | @@ -23928,9 +23928,20 @@ fn coerceExtra( | ... | @@ -23928,9 +23928,20 @@ fn coerceExtra( |
| 23928 | // cast from ?*T and ?[*]T to ?*anyopaque | 23928 | // cast from ?*T and ?[*]T to ?*anyopaque |
| 23929 | // but don't do it if the source type is a double pointer | 23929 | // but don't do it if the source type is a double pointer |
| 23930 | if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and | 23930 | if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and |
| 23931 | inst_ty.isPtrLikeOptional() and inst_ty.elemType2().zigTypeTag() != .Pointer) | 23931 | inst_ty.isPtrAtRuntime()) |
| 23932 | { | 23932 | anyopaque_check: { |
| 23933 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional; | 23933 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional; |
| 23934 | const elem_ty = inst_ty.elemType2(); | ||
| 23935 | if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) { | ||
| 23936 | in_memory_result = .{ .double_ptr_to_anyopaque = .{ | ||
| 23937 | .actual = inst_ty, | ||
| 23938 | .wanted = dest_ty, | ||
| 23939 | } }; | ||
| 23940 | break :optional; | ||
| 23941 | } | ||
| 23942 | // Let the logic below handle wrapping the optional now that | ||
| 23943 | // it has been checked to correctly coerce. | ||
| 23944 | if (!inst_ty.isPtrLikeOptional()) break: anyopaque_check; | ||
| 23934 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | 23945 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 23935 | } | 23946 | } |
| 23936 | 23947 | ||
| ... | @@ -24053,9 +24064,16 @@ fn coerceExtra( | ... | @@ -24053,9 +24064,16 @@ fn coerceExtra( |
| 24053 | 24064 | ||
| 24054 | // cast from *T and [*]T to *anyopaque | 24065 | // cast from *T and [*]T to *anyopaque |
| 24055 | // but don't do it if the source type is a double pointer | 24066 | // but don't do it if the source type is a double pointer |
| 24056 | if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and | 24067 | if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer) { |
| 24057 | inst_ty.childType().zigTypeTag() != .Pointer and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) | 24068 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; |
| 24058 | { | 24069 | const elem_ty = inst_ty.elemType2(); |
| 24070 | if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) { | ||
| 24071 | in_memory_result = .{ .double_ptr_to_anyopaque = .{ | ||
| 24072 | .actual = inst_ty, | ||
| 24073 | .wanted = dest_ty, | ||
| 24074 | } }; | ||
| 24075 | break :pointer; | ||
| 24076 | } | ||
| 24059 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | 24077 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 24060 | } | 24078 | } |
| 24061 | 24079 | ||
| ... | @@ -24537,6 +24555,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -24537,6 +24555,7 @@ const InMemoryCoercionResult = union(enum) { |
| 24537 | ptr_allowzero: Pair, | 24555 | ptr_allowzero: Pair, |
| 24538 | ptr_bit_range: BitRange, | 24556 | ptr_bit_range: BitRange, |
| 24539 | ptr_alignment: IntPair, | 24557 | ptr_alignment: IntPair, |
| 24558 | double_ptr_to_anyopaque: Pair, | ||
| 24540 | 24559 | ||
| 24541 | const Pair = struct { | 24560 | const Pair = struct { |
| 24542 | actual: Type, | 24561 | actual: Type, |
| ... | @@ -24829,6 +24848,12 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -24829,6 +24848,12 @@ const InMemoryCoercionResult = union(enum) { |
| 24829 | }); | 24848 | }); |
| 24830 | break; | 24849 | break; |
| 24831 | }, | 24850 | }, |
| 24851 | .double_ptr_to_anyopaque => |pair| { | ||
| 24852 | try sema.errNote(block, src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{ | ||
| 24853 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | ||
| 24854 | }); | ||
| 24855 | break; | ||
| 24856 | }, | ||
| 24832 | }; | 24857 | }; |
| 24833 | } | 24858 | } |
| 24834 | }; | 24859 | }; |
src/type.zig-3| ... | @@ -3941,10 +3941,7 @@ pub const Type = extern union { | ... | @@ -3941,10 +3941,7 @@ pub const Type = extern union { |
| 3941 | .optional => { | 3941 | .optional => { |
| 3942 | var buf: Payload.ElemType = undefined; | 3942 | var buf: Payload.ElemType = undefined; |
| 3943 | const child_type = self.optionalChild(&buf); | 3943 | const child_type = self.optionalChild(&buf); |
| 3944 | // optionals of zero sized pointers behave like bools | ||
| 3945 | if (!child_type.hasRuntimeBits()) return false; | ||
| 3946 | if (child_type.zigTypeTag() != .Pointer) return false; | 3944 | if (child_type.zigTypeTag() != .Pointer) return false; |
| 3947 | |||
| 3948 | const info = child_type.ptrInfo().data; | 3945 | const info = child_type.ptrInfo().data; |
| 3949 | switch (info.size) { | 3946 | switch (info.size) { |
| 3950 | .Slice, .C => return false, | 3947 | .Slice, .C => return false, |
test/cases/compile_errors/dont_implicit_cast_double_pointer_to_anyopaque.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | export fn entry() void { | ||
| 2 | var a: u32 = 1; | ||
| 3 | var ptr: *align(@alignOf(u32)) anyopaque = &a; | ||
| 4 | var b: *u32 = @ptrCast(*u32, ptr); | ||
| 5 | var ptr2: *anyopaque = &b; | ||
| 6 | _ = ptr2; | ||
| 7 | } | ||
| 8 | |||
| 9 | // error | ||
| 10 | // backend=stage2 | ||
| 11 | // target=native | ||
| 12 | // | ||
| 13 | // :5:28: error: expected type '*anyopaque', found '**u32' | ||
| 14 | // :5:28: note: pointer type child '*u32' cannot cast into pointer type child 'anyopaque' | ||
test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | pub export fn entry1() void { | ||
| 2 | const x: usize = 5; | ||
| 3 | |||
| 4 | const ptr: *const anyopaque = &(&x); | ||
| 5 | _ = ptr; | ||
| 6 | } | ||
| 7 | pub export fn entry2() void { | ||
| 8 | var val: [*:0]u8 = undefined; | ||
| 9 | func(&val); | ||
| 10 | } | ||
| 11 | fn func(_: ?*anyopaque) void {} | ||
| 12 | pub export fn entry3() void { | ||
| 13 | var x: *?*usize = undefined; | ||
| 14 | |||
| 15 | const ptr: *const anyopaque = x; | ||
| 16 | _ = ptr; | ||
| 17 | } | ||
| 18 | |||
| 19 | // error | ||
| 20 | // backend=stage2 | ||
| 21 | // target=native | ||
| 22 | // | ||
| 23 | // :4:35: error: expected type '*const anyopaque', found '*const *const usize' | ||
| 24 | // :4:35: note: cannot implicitly cast double pointer '*const *const usize' to anyopaque pointer '*const anyopaque' | ||
| 25 | // :9:10: error: expected type '?*anyopaque', found '*[*:0]u8' | ||
| 26 | // :9:10: note: cannot implicitly cast double pointer '*[*:0]u8' to anyopaque pointer '?*anyopaque' | ||
| 27 | // :15:35: error: expected type '*const anyopaque', found '*?*usize' | ||
| 28 | // :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque' | ||