| author | |
| committer | |
| log | 541b3e3a31946475f29d21e7a742bf80c5952791 |
| tree | 4516d103301ab7913786679f3f2e988bf7029eb5 |
| parent | fb91483e48fe6cfa21edc613f266e27bd6bf9dbf |
Closes #1288128 files changed, 243 insertions(+), 175 deletions(-)
lib/std/json.zig+3-3| ... | @@ -1560,7 +1560,7 @@ fn parseInternal( | ... | @@ -1560,7 +1560,7 @@ fn parseInternal( |
| 1560 | } | 1560 | } |
| 1561 | } | 1561 | } |
| 1562 | if (field.is_comptime) { | 1562 | if (field.is_comptime) { |
| 1563 | if (!try parsesTo(field.field_type, @ptrCast(*const field.field_type, field.default_value.?).*, tokens, child_options)) { | 1563 | if (!try parsesTo(field.field_type, @ptrCast(*align(1) const field.field_type, field.default_value.?).*, tokens, child_options)) { |
| 1564 | return error.UnexpectedValue; | 1564 | return error.UnexpectedValue; |
| 1565 | } | 1565 | } |
| 1566 | } else { | 1566 | } else { |
| ... | @@ -1587,7 +1587,7 @@ fn parseInternal( | ... | @@ -1587,7 +1587,7 @@ fn parseInternal( |
| 1587 | if (!fields_seen[i]) { | 1587 | if (!fields_seen[i]) { |
| 1588 | if (field.default_value) |default_ptr| { | 1588 | if (field.default_value) |default_ptr| { |
| 1589 | if (!field.is_comptime) { | 1589 | if (!field.is_comptime) { |
| 1590 | const default = @ptrCast(*const field.field_type, default_ptr).*; | 1590 | const default = @ptrCast(*align(1) const field.field_type, default_ptr).*; |
| 1591 | @field(r, field.name) = default; | 1591 | @field(r, field.name) = default; |
| 1592 | } | 1592 | } |
| 1593 | } else { | 1593 | } else { |
| ... | @@ -1667,7 +1667,7 @@ fn parseInternal( | ... | @@ -1667,7 +1667,7 @@ fn parseInternal( |
| 1667 | } | 1667 | } |
| 1668 | 1668 | ||
| 1669 | if (ptrInfo.sentinel) |some| { | 1669 | if (ptrInfo.sentinel) |some| { |
| 1670 | const sentinel_value = @ptrCast(*const ptrInfo.child, some).*; | 1670 | const sentinel_value = @ptrCast(*align(1) const ptrInfo.child, some).*; |
| 1671 | try arraylist.append(sentinel_value); | 1671 | try arraylist.append(sentinel_value); |
| 1672 | const output = arraylist.toOwnedSlice(); | 1672 | const output = arraylist.toOwnedSlice(); |
| 1673 | return output[0 .. output.len - 1 :sentinel_value]; | 1673 | return output[0 .. output.len - 1 :sentinel_value]; |
lib/std/mem.zig+12-11| ... | @@ -297,7 +297,7 @@ pub fn zeroes(comptime T: type) T { | ... | @@ -297,7 +297,7 @@ pub fn zeroes(comptime T: type) T { |
| 297 | }, | 297 | }, |
| 298 | .Array => |info| { | 298 | .Array => |info| { |
| 299 | if (info.sentinel) |sentinel_ptr| { | 299 | if (info.sentinel) |sentinel_ptr| { |
| 300 | const sentinel = @ptrCast(*const info.child, sentinel_ptr).*; | 300 | const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*; |
| 301 | return [_:sentinel]info.child{zeroes(info.child)} ** info.len; | 301 | return [_:sentinel]info.child{zeroes(info.child)} ** info.len; |
| 302 | } | 302 | } |
| 303 | return [_]info.child{zeroes(info.child)} ** info.len; | 303 | return [_]info.child{zeroes(info.child)} ** info.len; |
| ... | @@ -443,7 +443,7 @@ pub fn zeroInit(comptime T: type, init: anytype) T { | ... | @@ -443,7 +443,7 @@ pub fn zeroInit(comptime T: type, init: anytype) T { |
| 443 | 443 | ||
| 444 | inline for (struct_info.fields) |field| { | 444 | inline for (struct_info.fields) |field| { |
| 445 | if (field.default_value) |default_value_ptr| { | 445 | if (field.default_value) |default_value_ptr| { |
| 446 | const default_value = @ptrCast(*const field.field_type, default_value_ptr).*; | 446 | const default_value = @ptrCast(*align(1) const field.field_type, default_value_ptr).*; |
| 447 | @field(value, field.name) = default_value; | 447 | @field(value, field.name) = default_value; |
| 448 | } | 448 | } |
| 449 | } | 449 | } |
| ... | @@ -687,7 +687,7 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) { | ... | @@ -687,7 +687,7 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) { |
| 687 | const l = len(ptr); | 687 | const l = len(ptr); |
| 688 | const ptr_info = @typeInfo(Result).Pointer; | 688 | const ptr_info = @typeInfo(Result).Pointer; |
| 689 | if (ptr_info.sentinel) |s_ptr| { | 689 | if (ptr_info.sentinel) |s_ptr| { |
| 690 | const s = @ptrCast(*const ptr_info.child, s_ptr).*; | 690 | const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*; |
| 691 | return ptr[0..l :s]; | 691 | return ptr[0..l :s]; |
| 692 | } else { | 692 | } else { |
| 693 | return ptr[0..l]; | 693 | return ptr[0..l]; |
| ... | @@ -719,7 +719,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { | ... | @@ -719,7 +719,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { |
| 719 | // to find the value searched for, which is only the case if it matches | 719 | // to find the value searched for, which is only the case if it matches |
| 720 | // the sentinel of the type passed. | 720 | // the sentinel of the type passed. |
| 721 | if (array_info.sentinel) |sentinel_ptr| { | 721 | if (array_info.sentinel) |sentinel_ptr| { |
| 722 | const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*; | 722 | const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*; |
| 723 | if (end == sentinel) { | 723 | if (end == sentinel) { |
| 724 | new_ptr_info.sentinel = &end; | 724 | new_ptr_info.sentinel = &end; |
| 725 | } else { | 725 | } else { |
| ... | @@ -734,7 +734,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { | ... | @@ -734,7 +734,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { |
| 734 | // to find the value searched for, which is only the case if it matches | 734 | // to find the value searched for, which is only the case if it matches |
| 735 | // the sentinel of the type passed. | 735 | // the sentinel of the type passed. |
| 736 | if (ptr_info.sentinel) |sentinel_ptr| { | 736 | if (ptr_info.sentinel) |sentinel_ptr| { |
| 737 | const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*; | 737 | const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*; |
| 738 | if (end == sentinel) { | 738 | if (end == sentinel) { |
| 739 | new_ptr_info.sentinel = &end; | 739 | new_ptr_info.sentinel = &end; |
| 740 | } else { | 740 | } else { |
| ... | @@ -772,7 +772,7 @@ pub fn sliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) SliceTo(@Typ | ... | @@ -772,7 +772,7 @@ pub fn sliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) SliceTo(@Typ |
| 772 | const length = lenSliceTo(ptr, end); | 772 | const length = lenSliceTo(ptr, end); |
| 773 | const ptr_info = @typeInfo(Result).Pointer; | 773 | const ptr_info = @typeInfo(Result).Pointer; |
| 774 | if (ptr_info.sentinel) |s_ptr| { | 774 | if (ptr_info.sentinel) |s_ptr| { |
| 775 | const s = @ptrCast(*const ptr_info.child, s_ptr).*; | 775 | const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*; |
| 776 | return ptr[0..length :s]; | 776 | return ptr[0..length :s]; |
| 777 | } else { | 777 | } else { |
| 778 | return ptr[0..length]; | 778 | return ptr[0..length]; |
| ... | @@ -825,7 +825,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { | ... | @@ -825,7 +825,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { |
| 825 | .One => switch (@typeInfo(ptr_info.child)) { | 825 | .One => switch (@typeInfo(ptr_info.child)) { |
| 826 | .Array => |array_info| { | 826 | .Array => |array_info| { |
| 827 | if (array_info.sentinel) |sentinel_ptr| { | 827 | if (array_info.sentinel) |sentinel_ptr| { |
| 828 | const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*; | 828 | const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*; |
| 829 | if (sentinel == end) { | 829 | if (sentinel == end) { |
| 830 | return indexOfSentinel(array_info.child, end, ptr); | 830 | return indexOfSentinel(array_info.child, end, ptr); |
| 831 | } | 831 | } |
| ... | @@ -835,7 +835,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { | ... | @@ -835,7 +835,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { |
| 835 | else => {}, | 835 | else => {}, |
| 836 | }, | 836 | }, |
| 837 | .Many => if (ptr_info.sentinel) |sentinel_ptr| { | 837 | .Many => if (ptr_info.sentinel) |sentinel_ptr| { |
| 838 | const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*; | 838 | const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*; |
| 839 | // We may be looking for something other than the sentinel, | 839 | // We may be looking for something other than the sentinel, |
| 840 | // but iterating past the sentinel would be a bug so we need | 840 | // but iterating past the sentinel would be a bug so we need |
| 841 | // to check for both. | 841 | // to check for both. |
| ... | @@ -849,7 +849,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { | ... | @@ -849,7 +849,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { |
| 849 | }, | 849 | }, |
| 850 | .Slice => { | 850 | .Slice => { |
| 851 | if (ptr_info.sentinel) |sentinel_ptr| { | 851 | if (ptr_info.sentinel) |sentinel_ptr| { |
| 852 | const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*; | 852 | const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*; |
| 853 | if (sentinel == end) { | 853 | if (sentinel == end) { |
| 854 | return indexOfSentinel(ptr_info.child, sentinel, ptr); | 854 | return indexOfSentinel(ptr_info.child, sentinel, ptr); |
| 855 | } | 855 | } |
| ... | @@ -911,7 +911,7 @@ pub fn len(value: anytype) usize { | ... | @@ -911,7 +911,7 @@ pub fn len(value: anytype) usize { |
| 911 | .Many => { | 911 | .Many => { |
| 912 | const sentinel_ptr = info.sentinel orelse | 912 | const sentinel_ptr = info.sentinel orelse |
| 913 | @compileError("length of pointer with no sentinel"); | 913 | @compileError("length of pointer with no sentinel"); |
| 914 | const sentinel = @ptrCast(*const info.child, sentinel_ptr).*; | 914 | const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*; |
| 915 | return indexOfSentinel(info.child, sentinel, value); | 915 | return indexOfSentinel(info.child, sentinel, value); |
| 916 | }, | 916 | }, |
| 917 | .C => { | 917 | .C => { |
| ... | @@ -2882,7 +2882,8 @@ fn AsBytesReturnType(comptime P: type) type { | ... | @@ -2882,7 +2882,8 @@ fn AsBytesReturnType(comptime P: type) type { |
| 2882 | /// Given a pointer to a single item, returns a slice of the underlying bytes, preserving pointer attributes. | 2882 | /// Given a pointer to a single item, returns a slice of the underlying bytes, preserving pointer attributes. |
| 2883 | pub fn asBytes(ptr: anytype) AsBytesReturnType(@TypeOf(ptr)) { | 2883 | pub fn asBytes(ptr: anytype) AsBytesReturnType(@TypeOf(ptr)) { |
| 2884 | const P = @TypeOf(ptr); | 2884 | const P = @TypeOf(ptr); |
| 2885 | return @ptrCast(AsBytesReturnType(P), ptr); | 2885 | const T = AsBytesReturnType(P); |
| 2886 | return @ptrCast(T, @alignCast(meta.alignment(T), ptr)); | ||
| 2886 | } | 2887 | } |
| 2887 | 2888 | ||
| 2888 | test "asBytes" { | 2889 | test "asBytes" { |
lib/std/meta.zig+2-2| ... | @@ -204,12 +204,12 @@ pub fn sentinel(comptime T: type) ?Elem(T) { | ... | @@ -204,12 +204,12 @@ pub fn sentinel(comptime T: type) ?Elem(T) { |
| 204 | switch (info.size) { | 204 | switch (info.size) { |
| 205 | .Many, .Slice => { | 205 | .Many, .Slice => { |
| 206 | const sentinel_ptr = info.sentinel orelse return null; | 206 | const sentinel_ptr = info.sentinel orelse return null; |
| 207 | return @ptrCast(*const info.child, sentinel_ptr).*; | 207 | return @ptrCast(*align(1) const info.child, sentinel_ptr).*; |
| 208 | }, | 208 | }, |
| 209 | .One => switch (@typeInfo(info.child)) { | 209 | .One => switch (@typeInfo(info.child)) { |
| 210 | .Array => |array_info| { | 210 | .Array => |array_info| { |
| 211 | const sentinel_ptr = array_info.sentinel orelse return null; | 211 | const sentinel_ptr = array_info.sentinel orelse return null; |
| 212 | return @ptrCast(*const array_info.child, sentinel_ptr).*; | 212 | return @ptrCast(*align(1) const array_info.child, sentinel_ptr).*; |
| 213 | }, | 213 | }, |
| 214 | else => {}, | 214 | else => {}, |
| 215 | }, | 215 | }, |
lib/std/os/linux.zig+1-1| ... | @@ -888,7 +888,7 @@ else | ... | @@ -888,7 +888,7 @@ else |
| 888 | const vdso_clock_gettime_ty = if (builtin.zig_backend == .stage1) | 888 | const vdso_clock_gettime_ty = if (builtin.zig_backend == .stage1) |
| 889 | fn (i32, *timespec) callconv(.C) usize | 889 | fn (i32, *timespec) callconv(.C) usize |
| 890 | else | 890 | else |
| 891 | *const fn (i32, *timespec) callconv(.C) usize; | 891 | *align(1) const fn (i32, *timespec) callconv(.C) usize; |
| 892 | 892 | ||
| 893 | pub fn clock_gettime(clk_id: i32, tp: *timespec) usize { | 893 | pub fn clock_gettime(clk_id: i32, tp: *timespec) usize { |
| 894 | if (@hasDecl(VDSO, "CGT_SYM")) { | 894 | if (@hasDecl(VDSO, "CGT_SYM")) { |
lib/std/zig/c_translation.zig+1-1| ... | @@ -193,7 +193,7 @@ pub fn sizeof(target: anytype) usize { | ... | @@ -193,7 +193,7 @@ pub fn sizeof(target: anytype) usize { |
| 193 | const array_info = @typeInfo(ptr.child).Array; | 193 | const array_info = @typeInfo(ptr.child).Array; |
| 194 | if ((array_info.child == u8 or array_info.child == u16) and | 194 | if ((array_info.child == u8 or array_info.child == u16) and |
| 195 | array_info.sentinel != null and | 195 | array_info.sentinel != null and |
| 196 | @ptrCast(*const array_info.child, array_info.sentinel.?).* == 0) | 196 | @ptrCast(*align(1) const array_info.child, array_info.sentinel.?).* == 0) |
| 197 | { | 197 | { |
| 198 | // length of the string plus one for the null terminator. | 198 | // length of the string plus one for the null terminator. |
| 199 | return (array_info.len + 1) * @sizeOf(array_info.child); | 199 | return (array_info.len + 1) * @sizeOf(array_info.child); |
src/Sema.zig+64-17| ... | @@ -22811,6 +22811,7 @@ fn coerceExtra( | ... | @@ -22811,6 +22811,7 @@ fn coerceExtra( |
| 22811 | if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and | 22811 | if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and |
| 22812 | inst_ty.isPtrLikeOptional() and inst_ty.elemType2().zigTypeTag() != .Pointer) | 22812 | inst_ty.isPtrLikeOptional() and inst_ty.elemType2().zigTypeTag() != .Pointer) |
| 22813 | { | 22813 | { |
| 22814 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional; | ||
| 22814 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | 22815 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 22815 | } | 22816 | } |
| 22816 | 22817 | ||
| ... | @@ -22843,14 +22844,12 @@ fn coerceExtra( | ... | @@ -22843,14 +22844,12 @@ fn coerceExtra( |
| 22843 | single_item: { | 22844 | single_item: { |
| 22844 | if (dest_info.size != .One) break :single_item; | 22845 | if (dest_info.size != .One) break :single_item; |
| 22845 | if (!inst_ty.isSinglePointer()) break :single_item; | 22846 | if (!inst_ty.isSinglePointer()) break :single_item; |
| 22847 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; | ||
| 22846 | const ptr_elem_ty = inst_ty.childType(); | 22848 | const ptr_elem_ty = inst_ty.childType(); |
| 22847 | const array_ty = dest_info.pointee_type; | 22849 | const array_ty = dest_info.pointee_type; |
| 22848 | if (array_ty.zigTypeTag() != .Array) break :single_item; | 22850 | if (array_ty.zigTypeTag() != .Array) break :single_item; |
| 22849 | const array_elem_ty = array_ty.childType(); | 22851 | const array_elem_ty = array_ty.childType(); |
| 22850 | const dest_is_mut = dest_info.mutable; | 22852 | const dest_is_mut = dest_info.mutable; |
| 22851 | if (inst_ty.isConstPtr() and dest_is_mut) break :single_item; | ||
| 22852 | if (inst_ty.isVolatilePtr() and !dest_info.@"volatile") break :single_item; | ||
| 22853 | if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :single_item; | ||
| 22854 | switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) { | 22853 | switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) { |
| 22855 | .ok => {}, | 22854 | .ok => {}, |
| 22856 | else => break :single_item, | 22855 | else => break :single_item, |
| ... | @@ -22861,14 +22860,11 @@ fn coerceExtra( | ... | @@ -22861,14 +22860,11 @@ fn coerceExtra( |
| 22861 | // Coercions where the source is a single pointer to an array. | 22860 | // Coercions where the source is a single pointer to an array. |
| 22862 | src_array_ptr: { | 22861 | src_array_ptr: { |
| 22863 | if (!inst_ty.isSinglePointer()) break :src_array_ptr; | 22862 | if (!inst_ty.isSinglePointer()) break :src_array_ptr; |
| 22863 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; | ||
| 22864 | const array_ty = inst_ty.childType(); | 22864 | const array_ty = inst_ty.childType(); |
| 22865 | if (array_ty.zigTypeTag() != .Array) break :src_array_ptr; | 22865 | if (array_ty.zigTypeTag() != .Array) break :src_array_ptr; |
| 22866 | const len0 = array_ty.arrayLen() == 0; | ||
| 22867 | const array_elem_type = array_ty.childType(); | 22866 | const array_elem_type = array_ty.childType(); |
| 22868 | const dest_is_mut = dest_info.mutable; | 22867 | const dest_is_mut = dest_info.mutable; |
| 22869 | if (inst_ty.isConstPtr() and dest_is_mut and !len0) break :src_array_ptr; | ||
| 22870 | if (inst_ty.isVolatilePtr() and !dest_info.@"volatile") break :src_array_ptr; | ||
| 22871 | if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :src_array_ptr; | ||
| 22872 | 22868 | ||
| 22873 | const dst_elem_type = dest_info.pointee_type; | 22869 | const dst_elem_type = dest_info.pointee_type; |
| 22874 | switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src)) { | 22870 | switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src)) { |
| ... | @@ -22905,6 +22901,7 @@ fn coerceExtra( | ... | @@ -22905,6 +22901,7 @@ fn coerceExtra( |
| 22905 | 22901 | ||
| 22906 | // coercion from C pointer | 22902 | // coercion from C pointer |
| 22907 | if (inst_ty.isCPtr()) src_c_ptr: { | 22903 | if (inst_ty.isCPtr()) src_c_ptr: { |
| 22904 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :src_c_ptr; | ||
| 22908 | // In this case we must add a safety check because the C pointer | 22905 | // In this case we must add a safety check because the C pointer |
| 22909 | // could be null. | 22906 | // could be null. |
| 22910 | const src_elem_ty = inst_ty.childType(); | 22907 | const src_elem_ty = inst_ty.childType(); |
| ... | @@ -22920,7 +22917,7 @@ fn coerceExtra( | ... | @@ -22920,7 +22917,7 @@ fn coerceExtra( |
| 22920 | // cast from *T and [*]T to *anyopaque | 22917 | // cast from *T and [*]T to *anyopaque |
| 22921 | // but don't do it if the source type is a double pointer | 22918 | // but don't do it if the source type is a double pointer |
| 22922 | if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and | 22919 | if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and |
| 22923 | inst_ty.childType().zigTypeTag() != .Pointer) | 22920 | inst_ty.childType().zigTypeTag() != .Pointer and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) |
| 22924 | { | 22921 | { |
| 22925 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | 22922 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 22926 | } | 22923 | } |
| ... | @@ -22954,6 +22951,7 @@ fn coerceExtra( | ... | @@ -22954,6 +22951,7 @@ fn coerceExtra( |
| 22954 | return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src); | 22951 | return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src); |
| 22955 | }, | 22952 | }, |
| 22956 | .Pointer => p: { | 22953 | .Pointer => p: { |
| 22954 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :p; | ||
| 22957 | const inst_info = inst_ty.ptrInfo().data; | 22955 | const inst_info = inst_ty.ptrInfo().data; |
| 22958 | switch (try sema.coerceInMemoryAllowed( | 22956 | switch (try sema.coerceInMemoryAllowed( |
| 22959 | block, | 22957 | block, |
| ... | @@ -22984,7 +22982,7 @@ fn coerceExtra( | ... | @@ -22984,7 +22982,7 @@ fn coerceExtra( |
| 22984 | // pointer to anonymous struct to pointer to union | 22982 | // pointer to anonymous struct to pointer to union |
| 22985 | if (inst_ty.isSinglePointer() and | 22983 | if (inst_ty.isSinglePointer() and |
| 22986 | inst_ty.childType().isAnonStruct() and | 22984 | inst_ty.childType().isAnonStruct() and |
| 22987 | !dest_info.mutable) | 22985 | sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) |
| 22988 | { | 22986 | { |
| 22989 | return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src); | 22987 | return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 22990 | } | 22988 | } |
| ... | @@ -22993,7 +22991,7 @@ fn coerceExtra( | ... | @@ -22993,7 +22991,7 @@ fn coerceExtra( |
| 22993 | // pointer to anonymous struct to pointer to struct | 22991 | // pointer to anonymous struct to pointer to struct |
| 22994 | if (inst_ty.isSinglePointer() and | 22992 | if (inst_ty.isSinglePointer() and |
| 22995 | inst_ty.childType().isAnonStruct() and | 22993 | inst_ty.childType().isAnonStruct() and |
| 22996 | !dest_info.mutable) | 22994 | sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) |
| 22997 | { | 22995 | { |
| 22998 | return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src); | 22996 | return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 22999 | } | 22997 | } |
| ... | @@ -23002,7 +23000,7 @@ fn coerceExtra( | ... | @@ -23002,7 +23000,7 @@ fn coerceExtra( |
| 23002 | // pointer to tuple to pointer to array | 23000 | // pointer to tuple to pointer to array |
| 23003 | if (inst_ty.isSinglePointer() and | 23001 | if (inst_ty.isSinglePointer() and |
| 23004 | inst_ty.childType().isTuple() and | 23002 | inst_ty.childType().isTuple() and |
| 23005 | !dest_info.mutable) | 23003 | sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) |
| 23006 | { | 23004 | { |
| 23007 | return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src); | 23005 | return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 23008 | } | 23006 | } |
| ... | @@ -23011,10 +23009,8 @@ fn coerceExtra( | ... | @@ -23011,10 +23009,8 @@ fn coerceExtra( |
| 23011 | }, | 23009 | }, |
| 23012 | .Slice => { | 23010 | .Slice => { |
| 23013 | // pointer to tuple to slice | 23011 | // pointer to tuple to slice |
| 23014 | if (inst_ty.isSinglePointer() and | 23012 | if (inst_ty.isSinglePointer() and inst_ty.childType().isTuple() and dest_info.size == .Slice and |
| 23015 | inst_ty.childType().isTuple() and | 23013 | sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) |
| 23016 | (!dest_info.mutable or inst_ty.ptrIsMutable() or inst_ty.childType().tupleFields().types.len == 0) and | ||
| 23017 | dest_info.size == .Slice) | ||
| 23018 | { | 23014 | { |
| 23019 | return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src); | 23015 | return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 23020 | } | 23016 | } |
| ... | @@ -23043,6 +23039,7 @@ fn coerceExtra( | ... | @@ -23043,6 +23039,7 @@ fn coerceExtra( |
| 23043 | }, | 23039 | }, |
| 23044 | .Many => p: { | 23040 | .Many => p: { |
| 23045 | if (!inst_ty.isSlice()) break :p; | 23041 | if (!inst_ty.isSlice()) break :p; |
| 23042 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :p; | ||
| 23046 | const inst_info = inst_ty.ptrInfo().data; | 23043 | const inst_info = inst_ty.ptrInfo().data; |
| 23047 | 23044 | ||
| 23048 | switch (try sema.coerceInMemoryAllowed( | 23045 | switch (try sema.coerceInMemoryAllowed( |
| ... | @@ -25438,6 +25435,57 @@ fn coerceArrayPtrToSlice( | ... | @@ -25438,6 +25435,57 @@ fn coerceArrayPtrToSlice( |
| 25438 | return block.addTyOp(.array_to_slice, dest_ty, inst); | 25435 | return block.addTyOp(.array_to_slice, dest_ty, inst); |
| 25439 | } | 25436 | } |
| 25440 | 25437 | ||
| 25438 | fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool { | ||
| 25439 | const dest_info = dest_ty.ptrInfo().data; | ||
| 25440 | const inst_info = inst_ty.ptrInfo().data; | ||
| 25441 | const len0 = (inst_info.pointee_type.zigTypeTag() == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel() == 0 or | ||
| 25442 | (inst_info.pointee_type.arrayLen() == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or | ||
| 25443 | (inst_info.pointee_type.isTuple() and inst_info.pointee_type.tupleFields().types.len == 0); | ||
| 25444 | |||
| 25445 | const ok_cv_qualifiers = | ||
| 25446 | ((inst_info.mutable or !dest_info.mutable) or len0) and | ||
| 25447 | (!inst_info.@"volatile" or dest_info.@"volatile"); | ||
| 25448 | |||
| 25449 | if (!ok_cv_qualifiers) { | ||
| 25450 | in_memory_result.* = .{ .ptr_qualifiers = .{ | ||
| 25451 | .actual_const = !inst_info.mutable, | ||
| 25452 | .wanted_const = !dest_info.mutable, | ||
| 25453 | .actual_volatile = inst_info.@"volatile", | ||
| 25454 | .wanted_volatile = dest_info.@"volatile", | ||
| 25455 | } }; | ||
| 25456 | return false; | ||
| 25457 | } | ||
| 25458 | if (dest_info.@"addrspace" != inst_info.@"addrspace") { | ||
| 25459 | in_memory_result.* = .{ .ptr_addrspace = .{ | ||
| 25460 | .actual = inst_info.@"addrspace", | ||
| 25461 | .wanted = dest_info.@"addrspace", | ||
| 25462 | } }; | ||
| 25463 | return false; | ||
| 25464 | } | ||
| 25465 | if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true; | ||
| 25466 | if (len0) return true; | ||
| 25467 | const target = sema.mod.getTarget(); | ||
| 25468 | |||
| 25469 | const inst_align = if (inst_info.@"align" != 0) | ||
| 25470 | inst_info.@"align" | ||
| 25471 | else | ||
| 25472 | inst_info.pointee_type.abiAlignment(target); | ||
| 25473 | |||
| 25474 | const dest_align = if (dest_info.@"align" != 0) | ||
| 25475 | dest_info.@"align" | ||
| 25476 | else | ||
| 25477 | dest_info.pointee_type.abiAlignment(target); | ||
| 25478 | |||
| 25479 | if (dest_align > inst_align) { | ||
| 25480 | in_memory_result.* = .{ .ptr_alignment = .{ | ||
| 25481 | .actual = inst_align, | ||
| 25482 | .wanted = dest_align, | ||
| 25483 | } }; | ||
| 25484 | return false; | ||
| 25485 | } | ||
| 25486 | return true; | ||
| 25487 | } | ||
| 25488 | |||
| 25441 | fn coerceCompatiblePtrs( | 25489 | fn coerceCompatiblePtrs( |
| 25442 | sema: *Sema, | 25490 | sema: *Sema, |
| 25443 | block: *Block, | 25491 | block: *Block, |
| ... | @@ -25445,13 +25493,12 @@ fn coerceCompatiblePtrs( | ... | @@ -25445,13 +25493,12 @@ fn coerceCompatiblePtrs( |
| 25445 | inst: Air.Inst.Ref, | 25493 | inst: Air.Inst.Ref, |
| 25446 | inst_src: LazySrcLoc, | 25494 | inst_src: LazySrcLoc, |
| 25447 | ) !Air.Inst.Ref { | 25495 | ) !Air.Inst.Ref { |
| 25448 | // TODO check const/volatile/alignment | 25496 | const inst_ty = sema.typeOf(inst); |
| 25449 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { | 25497 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { |
| 25450 | // The comptime Value representation is compatible with both types. | 25498 | // The comptime Value representation is compatible with both types. |
| 25451 | return sema.addConstant(dest_ty, val); | 25499 | return sema.addConstant(dest_ty, val); |
| 25452 | } | 25500 | } |
| 25453 | try sema.requireRuntimeBlock(block, inst_src, null); | 25501 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 25454 | const inst_ty = sema.typeOf(inst); | ||
| 25455 | const inst_allows_zero = (inst_ty.zigTypeTag() == .Pointer and inst_ty.ptrAllowsZero()) or true; | 25502 | const inst_allows_zero = (inst_ty.zigTypeTag() == .Pointer and inst_ty.ptrAllowsZero()) or true; |
| 25456 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and | 25503 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and |
| 25457 | try sema.typeHasRuntimeBits(block, sema.src, dest_ty.elemType2())) | 25504 | try sema.typeHasRuntimeBits(block, sema.src, dest_ty.elemType2())) |
test/behavior/bugs/4328.zig+1-1| ... | @@ -13,7 +13,7 @@ extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE; | ... | @@ -13,7 +13,7 @@ extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE; |
| 13 | const S = extern struct { | 13 | const S = extern struct { |
| 14 | state: c_short, | 14 | state: c_short, |
| 15 | 15 | ||
| 16 | extern fn s_do_thing([*c]S, b: c_int) c_short; | 16 | extern fn s_do_thing([*c]const S, b: c_int) c_short; |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | test "Extern function calls in @TypeOf" { | 19 | test "Extern function calls in @TypeOf" { |
test/behavior/cast.zig+2-2| ... | @@ -1242,13 +1242,13 @@ test "implicit cast *[0]T to E![]const u8" { | ... | @@ -1242,13 +1242,13 @@ test "implicit cast *[0]T to E![]const u8" { |
| 1242 | 1242 | ||
| 1243 | var global_array: [4]u8 = undefined; | 1243 | var global_array: [4]u8 = undefined; |
| 1244 | test "cast from array reference to fn: comptime fn ptr" { | 1244 | test "cast from array reference to fn: comptime fn ptr" { |
| 1245 | const f = @ptrCast(*const fn () callconv(.C) void, &global_array); | 1245 | const f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array); |
| 1246 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); | 1246 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); |
| 1247 | } | 1247 | } |
| 1248 | test "cast from array reference to fn: runtime fn ptr" { | 1248 | test "cast from array reference to fn: runtime fn ptr" { |
| 1249 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 1249 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1250 | 1250 | ||
| 1251 | var f = @ptrCast(*const fn () callconv(.C) void, &global_array); | 1251 | var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array); |
| 1252 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); | 1252 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); |
| 1253 | } | 1253 | } |
| 1254 | 1254 |
test/behavior/slice.zig+2-1| ... | @@ -322,11 +322,12 @@ test "empty array to slice" { | ... | @@ -322,11 +322,12 @@ test "empty array to slice" { |
| 322 | 322 | ||
| 323 | test "@ptrCast slice to pointer" { | 323 | test "@ptrCast slice to pointer" { |
| 324 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 324 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 325 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 325 | 326 | ||
| 326 | const S = struct { | 327 | const S = struct { |
| 327 | fn doTheTest() !void { | 328 | fn doTheTest() !void { |
| 328 | var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff }; | 329 | var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff }; |
| 329 | var slice: []u8 = &array; | 330 | var slice: []align(@alignOf(u16)) u8 = &array; |
| 330 | var ptr = @ptrCast(*u16, slice); | 331 | var ptr = @ptrCast(*u16, slice); |
| 331 | try expect(ptr.* == 65535); | 332 | try expect(ptr.* == 65535); |
| 332 | } | 333 | } |
test/behavior/struct.zig+1-1| ... | @@ -521,7 +521,7 @@ test "packed struct fields are ordered from LSB to MSB" { | ... | @@ -521,7 +521,7 @@ test "packed struct fields are ordered from LSB to MSB" { |
| 521 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 521 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 522 | 522 | ||
| 523 | var all: u64 = 0x7765443322221111; | 523 | var all: u64 = 0x7765443322221111; |
| 524 | var bytes: [8]u8 = undefined; | 524 | var bytes: [8]u8 align(@alignOf(Bitfields)) = undefined; |
| 525 | @memcpy(&bytes, @ptrCast([*]u8, &all), 8); | 525 | @memcpy(&bytes, @ptrCast([*]u8, &all), 8); |
| 526 | var bitfields = @ptrCast(*Bitfields, &bytes).*; | 526 | var bitfields = @ptrCast(*Bitfields, &bytes).*; |
| 527 | 527 |
test/behavior/type.zig+2-2| ... | @@ -293,7 +293,7 @@ test "Type.Struct" { | ... | @@ -293,7 +293,7 @@ test "Type.Struct" { |
| 293 | try testing.expectEqual(@as(?*const anyopaque, null), infoB.fields[0].default_value); | 293 | try testing.expectEqual(@as(?*const anyopaque, null), infoB.fields[0].default_value); |
| 294 | try testing.expectEqualSlices(u8, "y", infoB.fields[1].name); | 294 | try testing.expectEqualSlices(u8, "y", infoB.fields[1].name); |
| 295 | try testing.expectEqual(u32, infoB.fields[1].field_type); | 295 | try testing.expectEqual(u32, infoB.fields[1].field_type); |
| 296 | try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoB.fields[1].default_value.?).*); | 296 | try testing.expectEqual(@as(u32, 5), @ptrCast(*align(1) const u32, infoB.fields[1].default_value.?).*); |
| 297 | try testing.expectEqual(@as(usize, 0), infoB.decls.len); | 297 | try testing.expectEqual(@as(usize, 0), infoB.decls.len); |
| 298 | try testing.expectEqual(@as(bool, false), infoB.is_tuple); | 298 | try testing.expectEqual(@as(bool, false), infoB.is_tuple); |
| 299 | 299 | ||
| ... | @@ -305,7 +305,7 @@ test "Type.Struct" { | ... | @@ -305,7 +305,7 @@ test "Type.Struct" { |
| 305 | try testing.expectEqual(@as(u8, 3), @ptrCast(*const u8, infoC.fields[0].default_value.?).*); | 305 | try testing.expectEqual(@as(u8, 3), @ptrCast(*const u8, infoC.fields[0].default_value.?).*); |
| 306 | try testing.expectEqualSlices(u8, "y", infoC.fields[1].name); | 306 | try testing.expectEqualSlices(u8, "y", infoC.fields[1].name); |
| 307 | try testing.expectEqual(u32, infoC.fields[1].field_type); | 307 | try testing.expectEqual(u32, infoC.fields[1].field_type); |
| 308 | try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoC.fields[1].default_value.?).*); | 308 | try testing.expectEqual(@as(u32, 5), @ptrCast(*align(1) const u32, infoC.fields[1].default_value.?).*); |
| 309 | try testing.expectEqual(@as(usize, 0), infoC.decls.len); | 309 | try testing.expectEqual(@as(usize, 0), infoC.decls.len); |
| 310 | try testing.expectEqual(@as(bool, false), infoC.is_tuple); | 310 | try testing.expectEqual(@as(bool, false), infoC.is_tuple); |
| 311 | 311 |
test/behavior/type_info.zig+3-3| ... | @@ -295,8 +295,8 @@ fn testStruct() !void { | ... | @@ -295,8 +295,8 @@ fn testStruct() !void { |
| 295 | try expect(unpacked_struct_info.Struct.is_tuple == false); | 295 | try expect(unpacked_struct_info.Struct.is_tuple == false); |
| 296 | try expect(unpacked_struct_info.Struct.backing_integer == null); | 296 | try expect(unpacked_struct_info.Struct.backing_integer == null); |
| 297 | try expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32)); | 297 | try expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32)); |
| 298 | try expect(@ptrCast(*const u32, unpacked_struct_info.Struct.fields[0].default_value.?).* == 4); | 298 | try expect(@ptrCast(*align(1) const u32, unpacked_struct_info.Struct.fields[0].default_value.?).* == 4); |
| 299 | try expect(mem.eql(u8, "foobar", @ptrCast(*const *const [6:0]u8, unpacked_struct_info.Struct.fields[1].default_value.?).*)); | 299 | try expect(mem.eql(u8, "foobar", @ptrCast(*align(1) const *const [6:0]u8, unpacked_struct_info.Struct.fields[1].default_value.?).*)); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | const TestStruct = struct { | 302 | const TestStruct = struct { |
| ... | @@ -321,7 +321,7 @@ fn testPackedStruct() !void { | ... | @@ -321,7 +321,7 @@ fn testPackedStruct() !void { |
| 321 | try expect(struct_info.Struct.fields[0].alignment == 0); | 321 | try expect(struct_info.Struct.fields[0].alignment == 0); |
| 322 | try expect(struct_info.Struct.fields[2].field_type == f32); | 322 | try expect(struct_info.Struct.fields[2].field_type == f32); |
| 323 | try expect(struct_info.Struct.fields[2].default_value == null); | 323 | try expect(struct_info.Struct.fields[2].default_value == null); |
| 324 | try expect(@ptrCast(*const u32, struct_info.Struct.fields[3].default_value.?).* == 4); | 324 | try expect(@ptrCast(*align(1) const u32, struct_info.Struct.fields[3].default_value.?).* == 4); |
| 325 | try expect(struct_info.Struct.fields[3].alignment == 0); | 325 | try expect(struct_info.Struct.fields[3].alignment == 0); |
| 326 | try expect(struct_info.Struct.decls.len == 2); | 326 | try expect(struct_info.Struct.decls.len == 2); |
| 327 | try expect(struct_info.Struct.decls[0].is_pub); | 327 | try expect(struct_info.Struct.decls[0].is_pub); |
test/cases/compile_errors/attempted_implicit_cast_from_const_T_to_sliceT.zig+1| ... | @@ -9,3 +9,4 @@ export fn entry() void { | ... | @@ -9,3 +9,4 @@ export fn entry() void { |
| 9 | // target=native | 9 | // target=native |
| 10 | // | 10 | // |
| 11 | // :3:22: error: expected type '[]u32', found '*const u32' | 11 | // :3:22: error: expected type '[]u32', found '*const u32' |
| 12 | // :3:22: note: cast discards const qualifier |
test/cases/compile_errors/implicit_cast_between_C_pointer_and_Zig_pointer-bad_const-align-child.zig created+47| ... | @@ -0,0 +1,47 @@ | ||
| 1 | export fn a() void { | ||
| 2 | var x: [*c]u8 = undefined; | ||
| 3 | var y: *align(4) u8 = x; | ||
| 4 | _ = y; | ||
| 5 | } | ||
| 6 | export fn b() void { | ||
| 7 | var x: [*c]const u8 = undefined; | ||
| 8 | var y: *u8 = x; | ||
| 9 | _ = y; | ||
| 10 | } | ||
| 11 | export fn c() void { | ||
| 12 | var x: [*c]u8 = undefined; | ||
| 13 | var y: *u32 = x; | ||
| 14 | _ = y; | ||
| 15 | } | ||
| 16 | export fn d() void { | ||
| 17 | var y: *align(1) u32 = undefined; | ||
| 18 | var x: [*c]u32 = y; | ||
| 19 | _ = x; | ||
| 20 | } | ||
| 21 | export fn e() void { | ||
| 22 | var y: *const u8 = undefined; | ||
| 23 | var x: [*c]u8 = y; | ||
| 24 | _ = x; | ||
| 25 | } | ||
| 26 | export fn f() void { | ||
| 27 | var y: *u8 = undefined; | ||
| 28 | var x: [*c]u32 = y; | ||
| 29 | _ = x; | ||
| 30 | } | ||
| 31 | |||
| 32 | // error | ||
| 33 | // backend=stage2 | ||
| 34 | // target=native | ||
| 35 | // | ||
| 36 | // :3:27: error: expected type '*align(4) u8', found '[*c]u8' | ||
| 37 | // :3:27: note: pointer alignment '1' cannot cast into pointer alignment '4' | ||
| 38 | // :8:18: error: expected type '*u8', found '[*c]const u8' | ||
| 39 | // :8:18: note: cast discards const qualifier | ||
| 40 | // :13:19: error: expected type '*u32', found '[*c]u8' | ||
| 41 | // :13:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32' | ||
| 42 | // :18:22: error: expected type '[*c]u32', found '*align(1) u32' | ||
| 43 | // :18:22: note: pointer alignment '1' cannot cast into pointer alignment '4' | ||
| 44 | // :23:21: error: expected type '[*c]u8', found '*const u8' | ||
| 45 | // :23:21: note: cast discards const qualifier | ||
| 46 | // :28:22: error: expected type '[*c]u32', found '*u8' | ||
| 47 | // :28:22: note: pointer type child 'u8' cannot cast into pointer type child 'u32' | ||
test/cases/compile_errors/implicit_cast_const_array_to_mutable_slice.zig created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | export fn entry() void { | ||
| 2 | const buffer: [1]u8 = [_]u8{8}; | ||
| 3 | const sliceA: []u8 = &buffer; | ||
| 4 | _ = sliceA; | ||
| 5 | } | ||
| 6 | export fn entry1() void { | ||
| 7 | const str: *const [0:0]u8 = ""; | ||
| 8 | const slice: [:0]u8 = str; | ||
| 9 | _ = slice; | ||
| 10 | } | ||
| 11 | export fn entry2() void { | ||
| 12 | const str: *const [0:0]u8 = ""; | ||
| 13 | const many: [*]u8 = str; | ||
| 14 | _ = many; | ||
| 15 | } | ||
| 16 | |||
| 17 | // error | ||
| 18 | // backend=stage2 | ||
| 19 | // target=native | ||
| 20 | // | ||
| 21 | // :3:26: error: expected type '[]u8', found '*const [1]u8' | ||
| 22 | // :3:26: note: cast discards const qualifier | ||
| 23 | // :8:27: error: expected type '[:0]u8', found '*const [0:0]u8' | ||
| 24 | // :8:27: note: cast discards const qualifier | ||
| 25 | // :13:25: error: expected type '[*]u8', found '*const [0:0]u8' | ||
| 26 | // :13:25: note: cast discards const qualifier | ||
test/cases/compile_errors/implicitly_increasing_slice_alignment.zig created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | const Foo = packed struct { | ||
| 2 | a: u8, | ||
| 3 | b: u32, | ||
| 4 | }; | ||
| 5 | |||
| 6 | export fn entry() void { | ||
| 7 | var foo = Foo { .a = 1, .b = 10 }; | ||
| 8 | foo.b += 1; | ||
| 9 | bar(@as(*[1]u32, &foo.b)[0..]); | ||
| 10 | } | ||
| 11 | |||
| 12 | fn bar(x: []u32) void { | ||
| 13 | x[0] += 1; | ||
| 14 | } | ||
| 15 | |||
| 16 | // error | ||
| 17 | // backend=stage2 | ||
| 18 | // target=native | ||
| 19 | // | ||
| 20 | // :9:22: error: expected type '*[1]u32', found '*align(1) u32' | ||
| 21 | // :9:22: note: pointer alignment '1' cannot cast into pointer alignment '4' | ||
test/cases/compile_errors/issue_5221_invalid_struct_init_type_referenced_by_typeInfo_and_passed_into_function.zig created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | fn ignore(comptime param: anytype) void {_ = param;} | ||
| 2 | |||
| 3 | export fn foo() void { | ||
| 4 | const MyStruct = struct { | ||
| 5 | wrong_type: []u8 = "foo", | ||
| 6 | }; | ||
| 7 | |||
| 8 | comptime ignore(@typeInfo(MyStruct).Struct.fields[0]); | ||
| 9 | } | ||
| 10 | |||
| 11 | // error | ||
| 12 | // backend=stage2 | ||
| 13 | // target=native | ||
| 14 | // | ||
| 15 | // :4:22: error: expected type '[]u8', found '*const [3:0]u8' | ||
| 16 | // :4:22: note: cast discards const qualifier | ||
test/cases/compile_errors/load_too_many_bytes_from_comptime_reinterpreted_pointer.zig+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | export fn entry() void { | 1 | export fn entry() void { |
| 2 | const float: f32 = 5.99999999999994648725e-01; | 2 | const float: f32 align(@alignOf(i64)) = 5.99999999999994648725e-01; |
| 3 | const float_ptr = &float; | 3 | const float_ptr = &float; |
| 4 | const int_ptr = @ptrCast(*const i64, float_ptr); | 4 | const int_ptr = @ptrCast(*const i64, float_ptr); |
| 5 | const int_val = int_ptr.*; | 5 | const int_val = int_ptr.*; |
test/cases/compile_errors/peer_cast_then_implicit_cast_const_pointer_to_mutable_C_pointer.zig created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | export fn func() void { | ||
| 2 | var strValue: [*c]u8 = undefined; | ||
| 3 | strValue = strValue orelse ""; | ||
| 4 | } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage2 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // :3:32: error: expected type '[*c]u8', found '*const [0:0]u8' | ||
| 11 | // :3:32: note: cast discards const qualifier | ||
test/cases/compile_errors/pointer_attributes_checked_when_coercing_pointer_to_anon_literal.zig created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | comptime { | ||
| 2 | const c: [][]const u8 = &.{ "hello", "world" }; | ||
| 3 | _ = c; | ||
| 4 | } | ||
| 5 | comptime { | ||
| 6 | const c: *[2][]const u8 = &.{ "hello", "world" }; | ||
| 7 | _ = c; | ||
| 8 | } | ||
| 9 | const S = struct { a: u8 = 1, b: u32 = 2 }; | ||
| 10 | comptime { | ||
| 11 | const c: *S = &.{ .a = 2 }; | ||
| 12 | _ = c; | ||
| 13 | } | ||
| 14 | |||
| 15 | // error | ||
| 16 | // backend=stage2 | ||
| 17 | // target=native | ||
| 18 | // | ||
| 19 | // :2:29: error: expected type '[][]const u8', found '*const tuple{comptime *const [5:0]u8 = "hello", comptime *const [5:0]u8 = "world"}' | ||
| 20 | // :2:29: note: cast discards const qualifier | ||
| 21 | // :6:31: error: expected type '*[2][]const u8', found '*const tuple{comptime *const [5:0]u8 = "hello", comptime *const [5:0]u8 = "world"}' | ||
| 22 | // :6:31: note: cast discards const qualifier | ||
| 23 | // :11:19: error: expected type '*tmp.S', found '*const struct{comptime a: comptime_int = 2}' | ||
| 24 | // :11:19: note: cast discards const qualifier | ||
test/cases/compile_errors/reading_past_end_of_pointer_casted_array.zig+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | comptime { | 1 | comptime { |
| 2 | const array: [4]u8 = "aoeu".*; | 2 | const array: [4]u8 = "aoeu".*; |
| 3 | const sub_array = array[1..]; | 3 | const sub_array = array[1..]; |
| 4 | const int_ptr = @ptrCast(*const u24, sub_array); | 4 | const int_ptr = @ptrCast(*const u24, @alignCast(@alignOf(u24), sub_array)); |
| 5 | const deref = int_ptr.*; | 5 | const deref = int_ptr.*; |
| 6 | _ = deref; | 6 | _ = deref; |
| 7 | } | 7 | } |
test/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | export fn foo() void { | 1 | export fn foo() void { |
| 2 | const bytes = [1]u8{ 0xfa } ** 16; | 2 | const bytes align(@alignOf([]const u8)) = [1]u8{0xfa} ** 16; |
| 3 | var value = @ptrCast(*const []const u8, &bytes).*; | 3 | var value = @ptrCast(*const []const u8, &bytes).*; |
| 4 | _ = value; | 4 | _ = value; |
| 5 | } | 5 | } |
test/cases/compile_errors/stage1/obj/implicit_cast_between_C_pointer_and_Zig_pointer-bad_const-align-child.zig deleted-42| ... | @@ -1,42 +0,0 @@ | ||
| 1 | export fn a() void { | ||
| 2 | var x: [*c]u8 = undefined; | ||
| 3 | var y: *align(4) u8 = x; | ||
| 4 | _ = y; | ||
| 5 | } | ||
| 6 | export fn b() void { | ||
| 7 | var x: [*c]const u8 = undefined; | ||
| 8 | var y: *u8 = x; | ||
| 9 | _ = y; | ||
| 10 | } | ||
| 11 | export fn c() void { | ||
| 12 | var x: [*c]u8 = undefined; | ||
| 13 | var y: *u32 = x; | ||
| 14 | _ = y; | ||
| 15 | } | ||
| 16 | export fn d() void { | ||
| 17 | var y: *align(1) u32 = undefined; | ||
| 18 | var x: [*c]u32 = y; | ||
| 19 | _ = x; | ||
| 20 | } | ||
| 21 | export fn e() void { | ||
| 22 | var y: *const u8 = undefined; | ||
| 23 | var x: [*c]u8 = y; | ||
| 24 | _ = x; | ||
| 25 | } | ||
| 26 | export fn f() void { | ||
| 27 | var y: *u8 = undefined; | ||
| 28 | var x: [*c]u32 = y; | ||
| 29 | _ = x; | ||
| 30 | } | ||
| 31 | |||
| 32 | // error | ||
| 33 | // backend=stage1 | ||
| 34 | // target=native | ||
| 35 | // | ||
| 36 | // tmp.zig:3:27: error: cast increases pointer alignment | ||
| 37 | // tmp.zig:8:18: error: cast discards const qualifier | ||
| 38 | // tmp.zig:13:19: error: expected type '*u32', found '[*c]u8' | ||
| 39 | // tmp.zig:13:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32' | ||
| 40 | // tmp.zig:18:22: error: cast increases pointer alignment | ||
| 41 | // tmp.zig:23:21: error: cast discards const qualifier | ||
| 42 | // tmp.zig:28:22: error: expected type '[*c]u32', found '*u8' | ||
test/cases/compile_errors/stage1/obj/implicit_cast_const_array_to_mutable_slice.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | export fn entry() void { | ||
| 2 | const buffer: [1]u8 = [_]u8{8}; | ||
| 3 | const sliceA: []u8 = &buffer; | ||
| 4 | _ = sliceA; | ||
| 5 | } | ||
| 6 | |||
| 7 | // error | ||
| 8 | // backend=stage1 | ||
| 9 | // target=native | ||
| 10 | // | ||
| 11 | // tmp.zig:3:27: error: cannot cast pointer to array literal to slice type '[]u8' | ||
| 12 | // tmp.zig:3:27: note: cast discards const qualifier | ||
test/cases/compile_errors/stage1/obj/implicitly_increasing_slice_alignment.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const Foo = packed struct { | ||
| 2 | a: u8, | ||
| 3 | b: u32, | ||
| 4 | }; | ||
| 5 | |||
| 6 | export fn entry() void { | ||
| 7 | var foo = Foo { .a = 1, .b = 10 }; | ||
| 8 | foo.b += 1; | ||
| 9 | bar(@as(*[1]u32, &foo.b)[0..]); | ||
| 10 | } | ||
| 11 | |||
| 12 | fn bar(x: []u32) void { | ||
| 13 | x[0] += 1; | ||
| 14 | } | ||
| 15 | |||
| 16 | // error | ||
| 17 | // backend=stage1 | ||
| 18 | // target=native | ||
| 19 | // | ||
| 20 | // tmp.zig:9:26: error: cast increases pointer alignment | ||
| 21 | // tmp.zig:9:26: note: '*align(1) u32' has alignment 1 | ||
| 22 | // tmp.zig:9:26: note: '*[1]u32' has alignment 4 | ||
test/cases/compile_errors/stage1/obj/issue_5221_invalid_struct_init_type_referenced_by_typeInfo_and_passed_into_function.zig deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | fn ignore(comptime param: anytype) void {_ = param;} | ||
| 2 | |||
| 3 | export fn foo() void { | ||
| 4 | const MyStruct = struct { | ||
| 5 | wrong_type: []u8 = "foo", | ||
| 6 | }; | ||
| 7 | |||
| 8 | comptime ignore(@typeInfo(MyStruct).Struct.fields[0]); | ||
| 9 | } | ||
| 10 | |||
| 11 | // error | ||
| 12 | // backend=stage1 | ||
| 13 | // target=native | ||
| 14 | // | ||
| 15 | // :5:28: error: cannot cast pointer to array literal to slice type '[]u8' | ||
| 16 | // :5:28: note: cast discards const qualifier | ||
test/cases/compile_errors/stage1/obj/peer_cast_then_implicit_cast_const_pointer_to_mutable_C_pointer.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | export fn func() void { | ||
| 2 | var strValue: [*c]u8 = undefined; | ||
| 3 | strValue = strValue orelse ""; | ||
| 4 | } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage1 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // tmp.zig:3:32: error: expected type '[*c]u8', found '*const [0:0]u8' | ||
| 11 | // tmp.zig:3:32: note: cast discards const qualifier | ||
test/cases/compile_errors/stage1/obj/pointer_attributes_checked_when_coercing_pointer_to_anon_literal.zig deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | comptime { | ||
| 2 | const c: [][]const u8 = &.{"hello", "world" }; | ||
| 3 | _ = c; | ||
| 4 | } | ||
| 5 | comptime { | ||
| 6 | const c: *[2][]const u8 = &.{"hello", "world" }; | ||
| 7 | _ = c; | ||
| 8 | } | ||
| 9 | const S = struct {a: u8 = 1, b: u32 = 2}; | ||
| 10 | comptime { | ||
| 11 | const c: *S = &.{}; | ||
| 12 | _ = c; | ||
| 13 | } | ||
| 14 | |||
| 15 | // error | ||
| 16 | // backend=stage1 | ||
| 17 | // target=native | ||
| 18 | // | ||
| 19 | // tmp.zig:2:31: error: cannot cast pointer to array literal to slice type '[][]const u8' | ||
| 20 | // tmp.zig:2:31: note: cast discards const qualifier | ||
| 21 | // tmp.zig:6:33: error: cannot cast pointer to array literal to '*[2][]const u8' | ||
| 22 | // tmp.zig:6:33: note: cast discards const qualifier | ||
| 23 | // tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21' | ||
| 24 | // tmp.zig:11:21: note: cast discards const qualifier | ||