| author | |
| committer | |
| log | a5c910adb610ae530db99f10aa77aaed3e85e830 |
| tree | 5c3f72dbac50fc9f09608be3d7ea328c629c00a0 |
| parent | 8d88dcdc61c61e3410138f4402482131f5074a80 |
Now they use slices or array pointers with any element type instead of
requiring byte pointers.
This is a breaking enhancement to the language.
The safety check for overlapping pointers will be implemented in a
future commit.
closes #1404033 files changed, 221 insertions(+), 280 deletions(-)
doc/langref.html.in+19-31| ... | @@ -8681,40 +8681,28 @@ test "integer cast panic" { | ... | @@ -8681,40 +8681,28 @@ test "integer cast panic" { |
| 8681 | {#header_close#} | 8681 | {#header_close#} |
| 8682 | 8682 | ||
| 8683 | {#header_open|@memcpy#} | 8683 | {#header_open|@memcpy#} |
| 8684 | <pre>{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize) void{#endsyntax#}</pre> | 8684 | <pre>{#syntax#}@memcpy(noalias dest, noalias source) void{#endsyntax#}</pre> |
| 8685 | <p> | 8685 | <p>This function copies bytes from one region of memory to another.</p> |
| 8686 | This function copies bytes from one region of memory to another. {#syntax#}dest{#endsyntax#} and | 8686 | <p>{#syntax#}dest{#endsyntax#} must be a mutable slice, or a mutable pointer to an array. |
| 8687 | {#syntax#}source{#endsyntax#} are both pointers and must not overlap. | 8687 | It may have any alignment, and it may have any element type.</p> |
| 8688 | </p> | 8688 | <p>{#syntax#}source{#endsyntax#} must be an array, pointer, or a slice |
| 8689 | <p> | 8689 | with the same element type as {#syntax#}dest{#endsyntax#}. It may have |
| 8690 | This function is a low level intrinsic with no safety mechanisms. Most code | 8690 | any alignment. Only {#syntax#}const{#endsyntax#} access is required. It |
| 8691 | should not use this function, instead using something like this: | 8691 | is sliced from 0 to the same length as |
| 8692 | </p> | 8692 | {#syntax#}dest{#endsyntax#}, triggering the same set of safety checks and |
| 8693 | <pre>{#syntax#}for (dest, source[0..byte_count]) |*d, s| d.* = s;{#endsyntax#}</pre> | 8693 | possible compile errors as |
| 8694 | <p> | 8694 | {#syntax#}source[0..dest.len]{#endsyntax#}.</p> |
| 8695 | The optimizer is intelligent enough to turn the above snippet into a memcpy. | 8695 | <p>It is illegal for {#syntax#}dest{#endsyntax#} and |
| 8696 | </p> | 8696 | {#syntax#}source[0..dest.len]{#endsyntax#} to overlap. If safety |
| 8697 | <p>There is also a standard library function for this:</p> | 8697 | checks are enabled, there will be a runtime check for such overlapping.</p> |
| 8698 | <pre>{#syntax#}const mem = @import("std").mem; | ||
| 8699 | mem.copy(u8, dest[0..byte_count], source[0..byte_count]);{#endsyntax#}</pre> | ||
| 8700 | {#header_close#} | 8698 | {#header_close#} |
| 8701 | 8699 | ||
| 8702 | {#header_open|@memset#} | 8700 | {#header_open|@memset#} |
| 8703 | <pre>{#syntax#}@memset(dest: [*]u8, c: u8, byte_count: usize) void{#endsyntax#}</pre> | 8701 | <pre>{#syntax#}@memset(dest, elem) void{#endsyntax#}</pre> |
| 8704 | <p> | 8702 | <p>This function sets all the elements of a memory region to {#syntax#}elem{#endsyntax#}.</p> |
| 8705 | This function sets a region of memory to {#syntax#}c{#endsyntax#}. {#syntax#}dest{#endsyntax#} is a pointer. | 8703 | <p>{#syntax#}dest{#endsyntax#} must be a mutable slice or a mutable pointer to an array. |
| 8706 | </p> | 8704 | It may have any alignment, and it may have any element type.</p> |
| 8707 | <p> | 8705 | <p>{#syntax#}elem{#endsyntax#} is coerced to the element type of {#syntax#}dest{#endsyntax#}.</p> |
| 8708 | This function is a low level intrinsic with no safety mechanisms. Most | ||
| 8709 | code should not use this function, instead using something like this: | ||
| 8710 | </p> | ||
| 8711 | <pre>{#syntax#}for (dest[0..byte_count]) |*b| b.* = c;{#endsyntax#}</pre> | ||
| 8712 | <p> | ||
| 8713 | The optimizer is intelligent enough to turn the above snippet into a memset. | ||
| 8714 | </p> | ||
| 8715 | <p>There is also a standard library function for this:</p> | ||
| 8716 | <pre>{#syntax#}const mem = @import("std").mem; | ||
| 8717 | mem.set(u8, dest, c);{#endsyntax#}</pre> | ||
| 8718 | {#header_close#} | 8706 | {#header_close#} |
| 8719 | 8707 | ||
| 8720 | {#header_open|@min#} | 8708 | {#header_open|@min#} |
lib/compiler_rt/atomics.zig+6-6| ... | @@ -121,22 +121,22 @@ fn __atomic_load(size: u32, src: [*]u8, dest: [*]u8, model: i32) callconv(.C) vo | ... | @@ -121,22 +121,22 @@ fn __atomic_load(size: u32, src: [*]u8, dest: [*]u8, model: i32) callconv(.C) vo |
| 121 | _ = model; | 121 | _ = model; |
| 122 | var sl = spinlocks.get(@ptrToInt(src)); | 122 | var sl = spinlocks.get(@ptrToInt(src)); |
| 123 | defer sl.release(); | 123 | defer sl.release(); |
| 124 | @memcpy(dest, src, size); | 124 | @memcpy(dest[0..size], src); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | fn __atomic_store(size: u32, dest: [*]u8, src: [*]u8, model: i32) callconv(.C) void { | 127 | fn __atomic_store(size: u32, dest: [*]u8, src: [*]u8, model: i32) callconv(.C) void { |
| 128 | _ = model; | 128 | _ = model; |
| 129 | var sl = spinlocks.get(@ptrToInt(dest)); | 129 | var sl = spinlocks.get(@ptrToInt(dest)); |
| 130 | defer sl.release(); | 130 | defer sl.release(); |
| 131 | @memcpy(dest, src, size); | 131 | @memcpy(dest[0..size], src); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | fn __atomic_exchange(size: u32, ptr: [*]u8, val: [*]u8, old: [*]u8, model: i32) callconv(.C) void { | 134 | fn __atomic_exchange(size: u32, ptr: [*]u8, val: [*]u8, old: [*]u8, model: i32) callconv(.C) void { |
| 135 | _ = model; | 135 | _ = model; |
| 136 | var sl = spinlocks.get(@ptrToInt(ptr)); | 136 | var sl = spinlocks.get(@ptrToInt(ptr)); |
| 137 | defer sl.release(); | 137 | defer sl.release(); |
| 138 | @memcpy(old, ptr, size); | 138 | @memcpy(old[0..size], ptr); |
| 139 | @memcpy(ptr, val, size); | 139 | @memcpy(ptr[0..size], val); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | fn __atomic_compare_exchange( | 142 | fn __atomic_compare_exchange( |
| ... | @@ -155,10 +155,10 @@ fn __atomic_compare_exchange( | ... | @@ -155,10 +155,10 @@ fn __atomic_compare_exchange( |
| 155 | if (expected[i] != b) break; | 155 | if (expected[i] != b) break; |
| 156 | } else { | 156 | } else { |
| 157 | // The two objects, ptr and expected, are equal | 157 | // The two objects, ptr and expected, are equal |
| 158 | @memcpy(ptr, desired, size); | 158 | @memcpy(ptr[0..size], desired); |
| 159 | return 1; | 159 | return 1; |
| 160 | } | 160 | } |
| 161 | @memcpy(expected, ptr, size); | 161 | @memcpy(expected[0..size], ptr); |
| 162 | return 0; | 162 | return 0; |
| 163 | } | 163 | } |
| 164 | 164 |
lib/compiler_rt/emutls.zig+2-2| ... | @@ -139,10 +139,10 @@ const ObjectArray = struct { | ... | @@ -139,10 +139,10 @@ const ObjectArray = struct { |
| 139 | 139 | ||
| 140 | if (control.default_value) |value| { | 140 | if (control.default_value) |value| { |
| 141 | // default value: copy the content to newly allocated object. | 141 | // default value: copy the content to newly allocated object. |
| 142 | @memcpy(data, @ptrCast([*]const u8, value), size); | 142 | @memcpy(data[0..size], @ptrCast([*]const u8, value)); |
| 143 | } else { | 143 | } else { |
| 144 | // no default: return zeroed memory. | 144 | // no default: return zeroed memory. |
| 145 | @memset(data, 0, size); | 145 | @memset(data[0..size], 0); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | self.slots[index] = @ptrCast(*anyopaque, data); | 148 | self.slots[index] = @ptrCast(*anyopaque, data); |
lib/std/array_hash_map.zig+2-2| ... | @@ -1893,7 +1893,7 @@ const IndexHeader = struct { | ... | @@ -1893,7 +1893,7 @@ const IndexHeader = struct { |
| 1893 | const index_size = hash_map.capacityIndexSize(new_bit_index); | 1893 | const index_size = hash_map.capacityIndexSize(new_bit_index); |
| 1894 | const nbytes = @sizeOf(IndexHeader) + index_size * len; | 1894 | const nbytes = @sizeOf(IndexHeader) + index_size * len; |
| 1895 | const bytes = try allocator.alignedAlloc(u8, @alignOf(IndexHeader), nbytes); | 1895 | const bytes = try allocator.alignedAlloc(u8, @alignOf(IndexHeader), nbytes); |
| 1896 | @memset(bytes.ptr + @sizeOf(IndexHeader), 0xff, bytes.len - @sizeOf(IndexHeader)); | 1896 | @memset(bytes[@sizeOf(IndexHeader)..], 0xff); |
| 1897 | const result = @ptrCast(*IndexHeader, bytes.ptr); | 1897 | const result = @ptrCast(*IndexHeader, bytes.ptr); |
| 1898 | result.* = .{ | 1898 | result.* = .{ |
| 1899 | .bit_index = new_bit_index, | 1899 | .bit_index = new_bit_index, |
| ... | @@ -1914,7 +1914,7 @@ const IndexHeader = struct { | ... | @@ -1914,7 +1914,7 @@ const IndexHeader = struct { |
| 1914 | const index_size = hash_map.capacityIndexSize(header.bit_index); | 1914 | const index_size = hash_map.capacityIndexSize(header.bit_index); |
| 1915 | const ptr = @ptrCast([*]align(@alignOf(IndexHeader)) u8, header); | 1915 | const ptr = @ptrCast([*]align(@alignOf(IndexHeader)) u8, header); |
| 1916 | const nbytes = @sizeOf(IndexHeader) + header.length() * index_size; | 1916 | const nbytes = @sizeOf(IndexHeader) + header.length() * index_size; |
| 1917 | @memset(ptr + @sizeOf(IndexHeader), 0xff, nbytes - @sizeOf(IndexHeader)); | 1917 | @memset(ptr[@sizeOf(IndexHeader)..nbytes], 0xff); |
| 1918 | } | 1918 | } |
| 1919 | 1919 | ||
| 1920 | // Verify that the header has sufficient alignment to produce aligned arrays. | 1920 | // Verify that the header has sufficient alignment to produce aligned arrays. |
lib/std/array_list.zig+4-12| ... | @@ -121,7 +121,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { | ... | @@ -121,7 +121,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 121 | 121 | ||
| 122 | const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len); | 122 | const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len); |
| 123 | mem.copy(T, new_memory, self.items); | 123 | mem.copy(T, new_memory, self.items); |
| 124 | @memset(@ptrCast([*]u8, self.items.ptr), undefined, self.items.len * @sizeOf(T)); | 124 | @memset(self.items, undefined); |
| 125 | self.clearAndFree(); | 125 | self.clearAndFree(); |
| 126 | return new_memory; | 126 | return new_memory; |
| 127 | } | 127 | } |
| ... | @@ -281,11 +281,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { | ... | @@ -281,11 +281,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 281 | const new_len = old_len + items.len; | 281 | const new_len = old_len + items.len; |
| 282 | assert(new_len <= self.capacity); | 282 | assert(new_len <= self.capacity); |
| 283 | self.items.len = new_len; | 283 | self.items.len = new_len; |
| 284 | @memcpy( | 284 | @memcpy(self.items[old_len..][0..items.len], items); |
| 285 | @ptrCast([*]align(@alignOf(T)) u8, self.items.ptr + old_len), | ||
| 286 | @ptrCast([*]const u8, items.ptr), | ||
| 287 | items.len * @sizeOf(T), | ||
| 288 | ); | ||
| 289 | } | 285 | } |
| 290 | 286 | ||
| 291 | pub const Writer = if (T != u8) | 287 | pub const Writer = if (T != u8) |
| ... | @@ -601,7 +597,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ | ... | @@ -601,7 +597,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 601 | 597 | ||
| 602 | const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len); | 598 | const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len); |
| 603 | mem.copy(T, new_memory, self.items); | 599 | mem.copy(T, new_memory, self.items); |
| 604 | @memset(@ptrCast([*]u8, self.items.ptr), undefined, self.items.len * @sizeOf(T)); | 600 | @memset(self.items, undefined); |
| 605 | self.clearAndFree(allocator); | 601 | self.clearAndFree(allocator); |
| 606 | return new_memory; | 602 | return new_memory; |
| 607 | } | 603 | } |
| ... | @@ -740,11 +736,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ | ... | @@ -740,11 +736,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 740 | const new_len = old_len + items.len; | 736 | const new_len = old_len + items.len; |
| 741 | assert(new_len <= self.capacity); | 737 | assert(new_len <= self.capacity); |
| 742 | self.items.len = new_len; | 738 | self.items.len = new_len; |
| 743 | @memcpy( | 739 | @memcpy(self.items[old_len..][0..items.len], items); |
| 744 | @ptrCast([*]align(@alignOf(T)) u8, self.items.ptr + old_len), | ||
| 745 | @ptrCast([*]const u8, items.ptr), | ||
| 746 | items.len * @sizeOf(T), | ||
| 747 | ); | ||
| 748 | } | 740 | } |
| 749 | 741 | ||
| 750 | pub const WriterContext = struct { | 742 | pub const WriterContext = struct { |
lib/std/c/darwin.zig+1-1| ... | @@ -3670,7 +3670,7 @@ pub const MachTask = extern struct { | ... | @@ -3670,7 +3670,7 @@ pub const MachTask = extern struct { |
| 3670 | else => |err| return unexpectedKernError(err), | 3670 | else => |err| return unexpectedKernError(err), |
| 3671 | } | 3671 | } |
| 3672 | 3672 | ||
| 3673 | @memcpy(out_buf[0..].ptr, @intToPtr([*]const u8, vm_memory), curr_bytes_read); | 3673 | @memcpy(out_buf[0..curr_bytes_read], @intToPtr([*]const u8, vm_memory)); |
| 3674 | _ = vm_deallocate(mach_task_self(), vm_memory, curr_bytes_read); | 3674 | _ = vm_deallocate(mach_task_self(), vm_memory, curr_bytes_read); |
| 3675 | 3675 | ||
| 3676 | out_buf = out_buf[curr_bytes_read..]; | 3676 | out_buf = out_buf[curr_bytes_read..]; |
lib/std/crypto/aes_gcm.zig+1-1| ... | @@ -91,7 +91,7 @@ fn AesGcm(comptime Aes: anytype) type { | ... | @@ -91,7 +91,7 @@ fn AesGcm(comptime Aes: anytype) type { |
| 91 | acc |= (computed_tag[p] ^ tag[p]); | 91 | acc |= (computed_tag[p] ^ tag[p]); |
| 92 | } | 92 | } |
| 93 | if (acc != 0) { | 93 | if (acc != 0) { |
| 94 | @memset(m.ptr, undefined, m.len); | 94 | @memset(m, undefined); |
| 95 | return error.AuthenticationFailed; | 95 | return error.AuthenticationFailed; |
| 96 | } | 96 | } |
| 97 | 97 |
lib/std/crypto/tls/Client.zig+1-1| ... | @@ -531,7 +531,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In | ... | @@ -531,7 +531,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 531 | const pub_key = subject.pubKey(); | 531 | const pub_key = subject.pubKey(); |
| 532 | if (pub_key.len > main_cert_pub_key_buf.len) | 532 | if (pub_key.len > main_cert_pub_key_buf.len) |
| 533 | return error.CertificatePublicKeyInvalid; | 533 | return error.CertificatePublicKeyInvalid; |
| 534 | @memcpy(&main_cert_pub_key_buf, pub_key.ptr, pub_key.len); | 534 | @memcpy(main_cert_pub_key_buf[0..pub_key.len], pub_key); |
| 535 | main_cert_pub_key_len = @intCast(@TypeOf(main_cert_pub_key_len), pub_key.len); | 535 | main_cert_pub_key_len = @intCast(@TypeOf(main_cert_pub_key_len), pub_key.len); |
| 536 | } else { | 536 | } else { |
| 537 | try prev_cert.verify(subject, now_sec); | 537 | try prev_cert.verify(subject, now_sec); |
lib/std/crypto/utils.zig+3-3| ... | @@ -135,11 +135,11 @@ pub fn timingSafeSub(comptime T: type, a: []const T, b: []const T, result: []T, | ... | @@ -135,11 +135,11 @@ pub fn timingSafeSub(comptime T: type, a: []const T, b: []const T, result: []T, |
| 135 | /// Sets a slice to zeroes. | 135 | /// Sets a slice to zeroes. |
| 136 | /// Prevents the store from being optimized out. | 136 | /// Prevents the store from being optimized out. |
| 137 | pub fn secureZero(comptime T: type, s: []T) void { | 137 | pub fn secureZero(comptime T: type, s: []T) void { |
| 138 | // NOTE: We do not use a volatile slice cast here since LLVM cannot | 138 | // TODO: implement `@memset` for non-byte-sized element type in the llvm backend |
| 139 | // see that it can be replaced by a memset. | 139 | //@memset(@as([]volatile T, s), 0); |
| 140 | const ptr = @ptrCast([*]volatile u8, s.ptr); | 140 | const ptr = @ptrCast([*]volatile u8, s.ptr); |
| 141 | const length = s.len * @sizeOf(T); | 141 | const length = s.len * @sizeOf(T); |
| 142 | @memset(ptr, 0, length); | 142 | @memset(ptr[0..length], 0); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | test "crypto.utils.timingSafeEql" { | 145 | test "crypto.utils.timingSafeEql" { |
lib/std/fifo.zig+4-4| ... | @@ -104,7 +104,7 @@ pub fn LinearFifo( | ... | @@ -104,7 +104,7 @@ pub fn LinearFifo( |
| 104 | } | 104 | } |
| 105 | { // set unused area to undefined | 105 | { // set unused area to undefined |
| 106 | const unused = mem.sliceAsBytes(self.buf[self.count..]); | 106 | const unused = mem.sliceAsBytes(self.buf[self.count..]); |
| 107 | @memset(unused.ptr, undefined, unused.len); | 107 | @memset(unused, undefined); |
| 108 | } | 108 | } |
| 109 | } | 109 | } |
| 110 | 110 | ||
| ... | @@ -182,12 +182,12 @@ pub fn LinearFifo( | ... | @@ -182,12 +182,12 @@ pub fn LinearFifo( |
| 182 | const slice = self.readableSliceMut(0); | 182 | const slice = self.readableSliceMut(0); |
| 183 | if (slice.len >= count) { | 183 | if (slice.len >= count) { |
| 184 | const unused = mem.sliceAsBytes(slice[0..count]); | 184 | const unused = mem.sliceAsBytes(slice[0..count]); |
| 185 | @memset(unused.ptr, undefined, unused.len); | 185 | @memset(unused, undefined); |
| 186 | } else { | 186 | } else { |
| 187 | const unused = mem.sliceAsBytes(slice[0..]); | 187 | const unused = mem.sliceAsBytes(slice[0..]); |
| 188 | @memset(unused.ptr, undefined, unused.len); | 188 | @memset(unused, undefined); |
| 189 | const unused2 = mem.sliceAsBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]); | 189 | const unused2 = mem.sliceAsBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]); |
| 190 | @memset(unused2.ptr, undefined, unused2.len); | 190 | @memset(unused2, undefined); |
| 191 | } | 191 | } |
| 192 | } | 192 | } |
| 193 | if (autoalign and self.count == count) { | 193 | if (autoalign and self.count == count) { |
lib/std/hash/murmur.zig+4-9| ... | @@ -115,7 +115,7 @@ pub const Murmur2_64 = struct { | ... | @@ -115,7 +115,7 @@ pub const Murmur2_64 = struct { |
| 115 | const offset = len - rest; | 115 | const offset = len - rest; |
| 116 | if (rest > 0) { | 116 | if (rest > 0) { |
| 117 | var k1: u64 = 0; | 117 | var k1: u64 = 0; |
| 118 | @memcpy(@ptrCast([*]u8, &k1), @ptrCast([*]const u8, &str[@intCast(usize, offset)]), @intCast(usize, rest)); | 118 | @memcpy(@ptrCast([*]u8, &k1)[0..@intCast(usize, rest)], @ptrCast([*]const u8, &str[@intCast(usize, offset)])); |
| 119 | if (native_endian == .Big) | 119 | if (native_endian == .Big) |
| 120 | k1 = @byteSwap(k1); | 120 | k1 = @byteSwap(k1); |
| 121 | h1 ^= k1; | 121 | h1 ^= k1; |
| ... | @@ -282,13 +282,8 @@ pub const Murmur3_32 = struct { | ... | @@ -282,13 +282,8 @@ pub const Murmur3_32 = struct { |
| 282 | 282 | ||
| 283 | fn SMHasherTest(comptime hash_fn: anytype, comptime hashbits: u32) u32 { | 283 | fn SMHasherTest(comptime hash_fn: anytype, comptime hashbits: u32) u32 { |
| 284 | const hashbytes = hashbits / 8; | 284 | const hashbytes = hashbits / 8; |
| 285 | var key: [256]u8 = undefined; | 285 | var key: [256]u8 = [1]u8{0} ** 256; |
| 286 | var hashes: [hashbytes * 256]u8 = undefined; | 286 | var hashes: [hashbytes * 256]u8 = [1]u8{0} ** (hashbytes * 256); |
| 287 | var final: [hashbytes]u8 = undefined; | ||
| 288 | |||
| 289 | @memset(@ptrCast([*]u8, &key[0]), 0, @sizeOf(@TypeOf(key))); | ||
| 290 | @memset(@ptrCast([*]u8, &hashes[0]), 0, @sizeOf(@TypeOf(hashes))); | ||
| 291 | @memset(@ptrCast([*]u8, &final[0]), 0, @sizeOf(@TypeOf(final))); | ||
| 292 | 287 | ||
| 293 | var i: u32 = 0; | 288 | var i: u32 = 0; |
| 294 | while (i < 256) : (i += 1) { | 289 | while (i < 256) : (i += 1) { |
| ... | @@ -297,7 +292,7 @@ fn SMHasherTest(comptime hash_fn: anytype, comptime hashbits: u32) u32 { | ... | @@ -297,7 +292,7 @@ fn SMHasherTest(comptime hash_fn: anytype, comptime hashbits: u32) u32 { |
| 297 | var h = hash_fn(key[0..i], 256 - i); | 292 | var h = hash_fn(key[0..i], 256 - i); |
| 298 | if (native_endian == .Big) | 293 | if (native_endian == .Big) |
| 299 | h = @byteSwap(h); | 294 | h = @byteSwap(h); |
| 300 | @memcpy(@ptrCast([*]u8, &hashes[i * hashbytes]), @ptrCast([*]u8, &h), hashbytes); | 295 | @memcpy(hashes[i * hashbytes..][0..hashbytes], @ptrCast([*]u8, &h)); |
| 301 | } | 296 | } |
| 302 | 297 | ||
| 303 | return @truncate(u32, hash_fn(&hashes, 0)); | 298 | return @truncate(u32, hash_fn(&hashes, 0)); |
lib/std/hash_map.zig+1-1| ... | @@ -1449,7 +1449,7 @@ pub fn HashMapUnmanaged( | ... | @@ -1449,7 +1449,7 @@ pub fn HashMapUnmanaged( |
| 1449 | } | 1449 | } |
| 1450 | 1450 | ||
| 1451 | fn initMetadatas(self: *Self) void { | 1451 | fn initMetadatas(self: *Self) void { |
| 1452 | @memset(@ptrCast([*]u8, self.metadata.?), 0, @sizeOf(Metadata) * self.capacity()); | 1452 | @memset(@ptrCast([*]u8, self.metadata.?)[0..@sizeOf(Metadata) * self.capacity()], 0); |
| 1453 | } | 1453 | } |
| 1454 | 1454 | ||
| 1455 | // This counts the number of occupied slots (not counting tombstones), which is | 1455 | // This counts the number of occupied slots (not counting tombstones), which is |
lib/std/heap/general_purpose_allocator.zig+4-3| ... | @@ -759,7 +759,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -759,7 +759,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 759 | const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size); | 759 | const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size); |
| 760 | if (new_size_class <= size_class) { | 760 | if (new_size_class <= size_class) { |
| 761 | if (old_mem.len > new_size) { | 761 | if (old_mem.len > new_size) { |
| 762 | @memset(old_mem.ptr + new_size, undefined, old_mem.len - new_size); | 762 | @memset(old_mem[new_size..], undefined); |
| 763 | } | 763 | } |
| 764 | if (config.verbose_log) { | 764 | if (config.verbose_log) { |
| 765 | log.info("small resize {d} bytes at {*} to {d}", .{ | 765 | log.info("small resize {d} bytes at {*} to {d}", .{ |
| ... | @@ -911,7 +911,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -911,7 +911,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 911 | self.empty_buckets = bucket; | 911 | self.empty_buckets = bucket; |
| 912 | } | 912 | } |
| 913 | } else { | 913 | } else { |
| 914 | @memset(old_mem.ptr, undefined, old_mem.len); | 914 | @memset(old_mem, undefined); |
| 915 | } | 915 | } |
| 916 | if (config.safety) { | 916 | if (config.safety) { |
| 917 | assert(self.small_allocations.remove(@ptrToInt(old_mem.ptr))); | 917 | assert(self.small_allocations.remove(@ptrToInt(old_mem.ptr))); |
| ... | @@ -1011,7 +1011,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -1011,7 +1011,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 1011 | }; | 1011 | }; |
| 1012 | self.buckets[bucket_index] = ptr; | 1012 | self.buckets[bucket_index] = ptr; |
| 1013 | // Set the used bits to all zeroes | 1013 | // Set the used bits to all zeroes |
| 1014 | @memset(@as(*[1]u8, ptr.usedBits(0)), 0, usedBitsCount(size_class)); | 1014 | @memset(@as([*]u8, @as(*[1]u8, ptr.usedBits(0)))[0..usedBitsCount(size_class)], 0); |
| 1015 | return ptr; | 1015 | return ptr; |
| 1016 | } | 1016 | } |
| 1017 | }; | 1017 | }; |
| ... | @@ -1412,3 +1412,4 @@ test "bug 9995 fix, large allocs count requested size not backing size" { | ... | @@ -1412,3 +1412,4 @@ test "bug 9995 fix, large allocs count requested size not backing size" { |
| 1412 | buf = try allocator.realloc(buf, 2); | 1412 | buf = try allocator.realloc(buf, 2); |
| 1413 | try std.testing.expect(gpa.total_requested_bytes == 2); | 1413 | try std.testing.expect(gpa.total_requested_bytes == 2); |
| 1414 | } | 1414 | } |
| 1415 |
lib/std/math/big/int_test.zig+4-4| ... | @@ -2756,7 +2756,7 @@ test "big int conversion read twos complement with padding" { | ... | @@ -2756,7 +2756,7 @@ test "big int conversion read twos complement with padding" { |
| 2756 | 2756 | ||
| 2757 | var buffer1 = try testing.allocator.alloc(u8, 16); | 2757 | var buffer1 = try testing.allocator.alloc(u8, 16); |
| 2758 | defer testing.allocator.free(buffer1); | 2758 | defer testing.allocator.free(buffer1); |
| 2759 | @memset(buffer1.ptr, 0xaa, buffer1.len); | 2759 | @memset(buffer1, 0xaa); |
| 2760 | 2760 | ||
| 2761 | // writeTwosComplement: | 2761 | // writeTwosComplement: |
| 2762 | // (1) should not write beyond buffer[0..abi_size] | 2762 | // (1) should not write beyond buffer[0..abi_size] |
| ... | @@ -2773,7 +2773,7 @@ test "big int conversion read twos complement with padding" { | ... | @@ -2773,7 +2773,7 @@ test "big int conversion read twos complement with padding" { |
| 2773 | a.toConst().writeTwosComplement(buffer1[0..16], .Big); | 2773 | a.toConst().writeTwosComplement(buffer1[0..16], .Big); |
| 2774 | try testing.expect(std.mem.eql(u8, buffer1, &[_]u8{ 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd })); | 2774 | try testing.expect(std.mem.eql(u8, buffer1, &[_]u8{ 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd })); |
| 2775 | 2775 | ||
| 2776 | @memset(buffer1.ptr, 0xaa, buffer1.len); | 2776 | @memset(buffer1, 0xaa); |
| 2777 | try a.set(-0x01_02030405_06070809_0a0b0c0d); | 2777 | try a.set(-0x01_02030405_06070809_0a0b0c0d); |
| 2778 | bit_count = 12 * 8 + 2; | 2778 | bit_count = 12 * 8 + 2; |
| 2779 | 2779 | ||
| ... | @@ -2794,7 +2794,7 @@ test "big int write twos complement +/- zero" { | ... | @@ -2794,7 +2794,7 @@ test "big int write twos complement +/- zero" { |
| 2794 | 2794 | ||
| 2795 | var buffer1 = try testing.allocator.alloc(u8, 16); | 2795 | var buffer1 = try testing.allocator.alloc(u8, 16); |
| 2796 | defer testing.allocator.free(buffer1); | 2796 | defer testing.allocator.free(buffer1); |
| 2797 | @memset(buffer1.ptr, 0xaa, buffer1.len); | 2797 | @memset(buffer1, 0xaa); |
| 2798 | 2798 | ||
| 2799 | // Test zero | 2799 | // Test zero |
| 2800 | 2800 | ||
| ... | @@ -2807,7 +2807,7 @@ test "big int write twos complement +/- zero" { | ... | @@ -2807,7 +2807,7 @@ test "big int write twos complement +/- zero" { |
| 2807 | m.toConst().writeTwosComplement(buffer1[0..16], .Big); | 2807 | m.toConst().writeTwosComplement(buffer1[0..16], .Big); |
| 2808 | try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 16)))); | 2808 | try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 16)))); |
| 2809 | 2809 | ||
| 2810 | @memset(buffer1.ptr, 0xaa, buffer1.len); | 2810 | @memset(buffer1, 0xaa); |
| 2811 | m.positive = false; | 2811 | m.positive = false; |
| 2812 | 2812 | ||
| 2813 | // Test negative zero | 2813 | // Test negative zero |
lib/std/mem/Allocator.zig+4-4| ... | @@ -215,7 +215,7 @@ pub fn allocAdvancedWithRetAddr( | ... | @@ -215,7 +215,7 @@ pub fn allocAdvancedWithRetAddr( |
| 215 | const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory; | 215 | const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory; |
| 216 | const byte_ptr = self.rawAlloc(byte_count, log2a(a), return_address) orelse return Error.OutOfMemory; | 216 | const byte_ptr = self.rawAlloc(byte_count, log2a(a), return_address) orelse return Error.OutOfMemory; |
| 217 | // TODO: https://github.com/ziglang/zig/issues/4298 | 217 | // TODO: https://github.com/ziglang/zig/issues/4298 |
| 218 | @memset(byte_ptr, undefined, byte_count); | 218 | @memset(byte_ptr[0..byte_count], undefined); |
| 219 | const byte_slice = byte_ptr[0..byte_count]; | 219 | const byte_slice = byte_ptr[0..byte_count]; |
| 220 | return mem.bytesAsSlice(T, @alignCast(a, byte_slice)); | 220 | return mem.bytesAsSlice(T, @alignCast(a, byte_slice)); |
| 221 | } | 221 | } |
| ... | @@ -282,9 +282,9 @@ pub fn reallocAdvanced( | ... | @@ -282,9 +282,9 @@ pub fn reallocAdvanced( |
| 282 | 282 | ||
| 283 | const new_mem = self.rawAlloc(byte_count, log2a(Slice.alignment), return_address) orelse | 283 | const new_mem = self.rawAlloc(byte_count, log2a(Slice.alignment), return_address) orelse |
| 284 | return error.OutOfMemory; | 284 | return error.OutOfMemory; |
| 285 | @memcpy(new_mem, old_byte_slice.ptr, @min(byte_count, old_byte_slice.len)); | 285 | @memcpy(new_mem[0..@min(byte_count, old_byte_slice.len)], old_byte_slice); |
| 286 | // TODO https://github.com/ziglang/zig/issues/4298 | 286 | // TODO https://github.com/ziglang/zig/issues/4298 |
| 287 | @memset(old_byte_slice.ptr, undefined, old_byte_slice.len); | 287 | @memset(old_byte_slice, undefined); |
| 288 | self.rawFree(old_byte_slice, log2a(Slice.alignment), return_address); | 288 | self.rawFree(old_byte_slice, log2a(Slice.alignment), return_address); |
| 289 | 289 | ||
| 290 | return mem.bytesAsSlice(T, @alignCast(Slice.alignment, new_mem[0..byte_count])); | 290 | return mem.bytesAsSlice(T, @alignCast(Slice.alignment, new_mem[0..byte_count])); |
| ... | @@ -299,7 +299,7 @@ pub fn free(self: Allocator, memory: anytype) void { | ... | @@ -299,7 +299,7 @@ pub fn free(self: Allocator, memory: anytype) void { |
| 299 | if (bytes_len == 0) return; | 299 | if (bytes_len == 0) return; |
| 300 | const non_const_ptr = @constCast(bytes.ptr); | 300 | const non_const_ptr = @constCast(bytes.ptr); |
| 301 | // TODO: https://github.com/ziglang/zig/issues/4298 | 301 | // TODO: https://github.com/ziglang/zig/issues/4298 |
| 302 | @memset(non_const_ptr, undefined, bytes_len); | 302 | @memset(non_const_ptr[0..bytes_len], undefined); |
| 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()); |
| 304 | } | 304 | } |
| 305 | 305 |
lib/std/multi_array_list.zig+1-2| ... | @@ -360,11 +360,10 @@ pub fn MultiArrayList(comptime T: type) type { | ... | @@ -360,11 +360,10 @@ pub fn MultiArrayList(comptime T: type) type { |
| 360 | if (@sizeOf(field_info.type) != 0) { | 360 | if (@sizeOf(field_info.type) != 0) { |
| 361 | const field = @intToEnum(Field, i); | 361 | const field = @intToEnum(Field, i); |
| 362 | const dest_slice = self_slice.items(field)[new_len..]; | 362 | const dest_slice = self_slice.items(field)[new_len..]; |
| 363 | const byte_count = dest_slice.len * @sizeOf(field_info.type); | ||
| 364 | // We use memset here for more efficient codegen in safety-checked, | 363 | // We use memset here for more efficient codegen in safety-checked, |
| 365 | // valgrind-enabled builds. Otherwise the valgrind client request | 364 | // valgrind-enabled builds. Otherwise the valgrind client request |
| 366 | // will be repeated for every element. | 365 | // will be repeated for every element. |
| 367 | @memset(@ptrCast([*]u8, dest_slice.ptr), undefined, byte_count); | 366 | @memset(dest_slice, undefined); |
| 368 | } | 367 | } |
| 369 | } | 368 | } |
| 370 | self.len = new_len; | 369 | self.len = new_len; |
lib/std/net.zig+3-3| ... | @@ -1020,7 +1020,7 @@ fn linuxLookupName( | ... | @@ -1020,7 +1020,7 @@ fn linuxLookupName( |
| 1020 | for (addrs.items, 0..) |*addr, i| { | 1020 | for (addrs.items, 0..) |*addr, i| { |
| 1021 | var key: i32 = 0; | 1021 | var key: i32 = 0; |
| 1022 | var sa6: os.sockaddr.in6 = undefined; | 1022 | var sa6: os.sockaddr.in6 = undefined; |
| 1023 | @memset(@ptrCast([*]u8, &sa6), 0, @sizeOf(os.sockaddr.in6)); | 1023 | @memset(@ptrCast([*]u8, &sa6)[0..@sizeOf(os.sockaddr.in6)], 0); |
| 1024 | var da6 = os.sockaddr.in6{ | 1024 | var da6 = os.sockaddr.in6{ |
| 1025 | .family = os.AF.INET6, | 1025 | .family = os.AF.INET6, |
| 1026 | .scope_id = addr.addr.in6.sa.scope_id, | 1026 | .scope_id = addr.addr.in6.sa.scope_id, |
| ... | @@ -1029,7 +1029,7 @@ fn linuxLookupName( | ... | @@ -1029,7 +1029,7 @@ fn linuxLookupName( |
| 1029 | .addr = [1]u8{0} ** 16, | 1029 | .addr = [1]u8{0} ** 16, |
| 1030 | }; | 1030 | }; |
| 1031 | var sa4: os.sockaddr.in = undefined; | 1031 | var sa4: os.sockaddr.in = undefined; |
| 1032 | @memset(@ptrCast([*]u8, &sa4), 0, @sizeOf(os.sockaddr.in)); | 1032 | @memset(@ptrCast([*]u8, &sa4)[0..@sizeOf(os.sockaddr.in)], 0); |
| 1033 | var da4 = os.sockaddr.in{ | 1033 | var da4 = os.sockaddr.in{ |
| 1034 | .family = os.AF.INET, | 1034 | .family = os.AF.INET, |
| 1035 | .port = 65535, | 1035 | .port = 65535, |
| ... | @@ -1577,7 +1577,7 @@ fn resMSendRc( | ... | @@ -1577,7 +1577,7 @@ fn resMSendRc( |
| 1577 | 1577 | ||
| 1578 | // Get local address and open/bind a socket | 1578 | // Get local address and open/bind a socket |
| 1579 | var sa: Address = undefined; | 1579 | var sa: Address = undefined; |
| 1580 | @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address)); | 1580 | @memset(@ptrCast([*]u8, &sa)[0..@sizeOf(Address)], 0); |
| 1581 | sa.any.family = family; | 1581 | sa.any.family = family; |
| 1582 | try os.bind(fd, &sa.any, sl); | 1582 | try os.bind(fd, &sa.any, sl); |
| 1583 | 1583 |
lib/std/os.zig+4-4| ... | @@ -5217,7 +5217,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { | ... | @@ -5217,7 +5217,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { |
| 5217 | .macos, .ios, .watchos, .tvos => { | 5217 | .macos, .ios, .watchos, .tvos => { |
| 5218 | // On macOS, we can use F.GETPATH fcntl command to query the OS for | 5218 | // On macOS, we can use F.GETPATH fcntl command to query the OS for |
| 5219 | // the path to the file descriptor. | 5219 | // the path to the file descriptor. |
| 5220 | @memset(out_buffer, 0, MAX_PATH_BYTES); | 5220 | @memset(out_buffer[0..MAX_PATH_BYTES], 0); |
| 5221 | switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { | 5221 | switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { |
| 5222 | .SUCCESS => {}, | 5222 | .SUCCESS => {}, |
| 5223 | .BADF => return error.FileNotFound, | 5223 | .BADF => return error.FileNotFound, |
| ... | @@ -5308,7 +5308,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { | ... | @@ -5308,7 +5308,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { |
| 5308 | if (comptime builtin.os.version_range.semver.max.order(.{ .major = 6, .minor = 0 }) == .lt) { | 5308 | if (comptime builtin.os.version_range.semver.max.order(.{ .major = 6, .minor = 0 }) == .lt) { |
| 5309 | @compileError("querying for canonical path of a handle is unsupported on this host"); | 5309 | @compileError("querying for canonical path of a handle is unsupported on this host"); |
| 5310 | } | 5310 | } |
| 5311 | @memset(out_buffer, 0, MAX_PATH_BYTES); | 5311 | @memset(out_buffer[0..MAX_PATH_BYTES], 0); |
| 5312 | switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { | 5312 | switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { |
| 5313 | .SUCCESS => {}, | 5313 | .SUCCESS => {}, |
| 5314 | .BADF => return error.FileNotFound, | 5314 | .BADF => return error.FileNotFound, |
| ... | @@ -5322,7 +5322,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { | ... | @@ -5322,7 +5322,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { |
| 5322 | if (comptime builtin.os.version_range.semver.max.order(.{ .major = 10, .minor = 0 }) == .lt) { | 5322 | if (comptime builtin.os.version_range.semver.max.order(.{ .major = 10, .minor = 0 }) == .lt) { |
| 5323 | @compileError("querying for canonical path of a handle is unsupported on this host"); | 5323 | @compileError("querying for canonical path of a handle is unsupported on this host"); |
| 5324 | } | 5324 | } |
| 5325 | @memset(out_buffer, 0, MAX_PATH_BYTES); | 5325 | @memset(out_buffer[0..MAX_PATH_BYTES], 0); |
| 5326 | switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { | 5326 | switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { |
| 5327 | .SUCCESS => {}, | 5327 | .SUCCESS => {}, |
| 5328 | .ACCES => return error.AccessDenied, | 5328 | .ACCES => return error.AccessDenied, |
| ... | @@ -5720,7 +5720,7 @@ pub fn res_mkquery( | ... | @@ -5720,7 +5720,7 @@ pub fn res_mkquery( |
| 5720 | 5720 | ||
| 5721 | // Construct query template - ID will be filled later | 5721 | // Construct query template - ID will be filled later |
| 5722 | var q: [280]u8 = undefined; | 5722 | var q: [280]u8 = undefined; |
| 5723 | @memset(&q, 0, n); | 5723 | @memset(q[0..n], 0); |
| 5724 | q[2] = @as(u8, op) * 8 + 1; | 5724 | q[2] = @as(u8, op) * 8 + 1; |
| 5725 | q[5] = 1; | 5725 | q[5] = 1; |
| 5726 | mem.copy(u8, q[13..], name); | 5726 | mem.copy(u8, q[13..], name); |
lib/std/os/linux.zig+3-3| ... | @@ -1184,7 +1184,7 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact | ... | @@ -1184,7 +1184,7 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact |
| 1184 | .mask = undefined, | 1184 | .mask = undefined, |
| 1185 | .restorer = @ptrCast(k_sigaction_funcs.restorer, restorer_fn), | 1185 | .restorer = @ptrCast(k_sigaction_funcs.restorer, restorer_fn), |
| 1186 | }; | 1186 | }; |
| 1187 | @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &new.mask), mask_size); | 1187 | @memcpy(@ptrCast([*]u8, &ksa.mask)[0..mask_size], @ptrCast([*]const u8, &new.mask)); |
| 1188 | } | 1188 | } |
| 1189 | 1189 | ||
| 1190 | const ksa_arg = if (act != null) @ptrToInt(&ksa) else 0; | 1190 | const ksa_arg = if (act != null) @ptrToInt(&ksa) else 0; |
| ... | @@ -1200,7 +1200,7 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact | ... | @@ -1200,7 +1200,7 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact |
| 1200 | if (oact) |old| { | 1200 | if (oact) |old| { |
| 1201 | old.handler.handler = oldksa.handler; | 1201 | old.handler.handler = oldksa.handler; |
| 1202 | old.flags = @truncate(c_uint, oldksa.flags); | 1202 | old.flags = @truncate(c_uint, oldksa.flags); |
| 1203 | @memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &oldksa.mask), mask_size); | 1203 | @memcpy(@ptrCast([*]u8, &old.mask)[0..mask_size], @ptrCast([*]const u8, &oldksa.mask)); |
| 1204 | } | 1204 | } |
| 1205 | 1205 | ||
| 1206 | return 0; | 1206 | return 0; |
| ... | @@ -1515,7 +1515,7 @@ pub fn sched_yield() usize { | ... | @@ -1515,7 +1515,7 @@ pub fn sched_yield() usize { |
| 1515 | pub fn sched_getaffinity(pid: pid_t, size: usize, set: *cpu_set_t) usize { | 1515 | pub fn sched_getaffinity(pid: pid_t, size: usize, set: *cpu_set_t) usize { |
| 1516 | const rc = syscall3(.sched_getaffinity, @bitCast(usize, @as(isize, pid)), size, @ptrToInt(set)); | 1516 | const rc = syscall3(.sched_getaffinity, @bitCast(usize, @as(isize, pid)), size, @ptrToInt(set)); |
| 1517 | if (@bitCast(isize, rc) < 0) return rc; | 1517 | if (@bitCast(isize, rc) < 0) return rc; |
| 1518 | if (rc < size) @memset(@ptrCast([*]u8, set) + rc, 0, size - rc); | 1518 | if (rc < size) @memset(@ptrCast([*]u8, set)[rc..size], 0); |
| 1519 | return 0; | 1519 | return 0; |
| 1520 | } | 1520 | } |
| 1521 | 1521 |
lib/std/os/windows.zig+3-3| ... | @@ -755,9 +755,9 @@ pub fn CreateSymbolicLink( | ... | @@ -755,9 +755,9 @@ pub fn CreateSymbolicLink( |
| 755 | }; | 755 | }; |
| 756 | 756 | ||
| 757 | std.mem.copy(u8, buffer[0..], std.mem.asBytes(&symlink_data)); | 757 | std.mem.copy(u8, buffer[0..], std.mem.asBytes(&symlink_data)); |
| 758 | @memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2); | 758 | @memcpy(buffer[@sizeOf(SYMLINK_DATA)..][0..target_path.len * 2], @ptrCast([*]const u8, target_path)); |
| 759 | const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2; | 759 | const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2; |
| 760 | @memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2); | 760 | @memcpy(buffer[paths_start..][0..target_path.len * 2], @ptrCast([*]const u8, target_path)); |
| 761 | _ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null); | 761 | _ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null); |
| 762 | } | 762 | } |
| 763 | 763 | ||
| ... | @@ -1179,7 +1179,7 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -1179,7 +1179,7 @@ pub fn GetFinalPathNameByHandle( |
| 1179 | var input_struct = @ptrCast(*MOUNTMGR_MOUNT_POINT, &input_buf[0]); | 1179 | var input_struct = @ptrCast(*MOUNTMGR_MOUNT_POINT, &input_buf[0]); |
| 1180 | input_struct.DeviceNameOffset = @sizeOf(MOUNTMGR_MOUNT_POINT); | 1180 | input_struct.DeviceNameOffset = @sizeOf(MOUNTMGR_MOUNT_POINT); |
| 1181 | input_struct.DeviceNameLength = @intCast(USHORT, volume_name_u16.len * 2); | 1181 | input_struct.DeviceNameLength = @intCast(USHORT, volume_name_u16.len * 2); |
| 1182 | @memcpy(input_buf[@sizeOf(MOUNTMGR_MOUNT_POINT)..], @ptrCast([*]const u8, volume_name_u16.ptr), volume_name_u16.len * 2); | 1182 | @memcpy(input_buf[@sizeOf(MOUNTMGR_MOUNT_POINT)..][0..volume_name_u16.len * 2], @ptrCast([*]const u8, volume_name_u16.ptr)); |
| 1183 | 1183 | ||
| 1184 | DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_POINTS, &input_buf, &output_buf) catch |err| switch (err) { | 1184 | DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_POINTS, &input_buf, &output_buf) catch |err| switch (err) { |
| 1185 | error.AccessDenied => unreachable, | 1185 | error.AccessDenied => unreachable, |
lib/std/zig/c_builtins.zig+2-2| ... | @@ -152,7 +152,7 @@ pub inline fn __builtin___memset_chk( | ... | @@ -152,7 +152,7 @@ pub inline fn __builtin___memset_chk( |
| 152 | 152 | ||
| 153 | pub inline fn __builtin_memset(dst: ?*anyopaque, val: c_int, len: usize) ?*anyopaque { | 153 | pub inline fn __builtin_memset(dst: ?*anyopaque, val: c_int, len: usize) ?*anyopaque { |
| 154 | const dst_cast = @ptrCast([*c]u8, dst); | 154 | const dst_cast = @ptrCast([*c]u8, dst); |
| 155 | @memset(dst_cast, @bitCast(u8, @truncate(i8, val)), len); | 155 | @memset(dst_cast[0..len], @bitCast(u8, @truncate(i8, val))); |
| 156 | return dst; | 156 | return dst; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| ... | @@ -174,7 +174,7 @@ pub inline fn __builtin_memcpy( | ... | @@ -174,7 +174,7 @@ pub inline fn __builtin_memcpy( |
| 174 | const dst_cast = @ptrCast([*c]u8, dst); | 174 | const dst_cast = @ptrCast([*c]u8, dst); |
| 175 | const src_cast = @ptrCast([*c]const u8, src); | 175 | const src_cast = @ptrCast([*c]const u8, src); |
| 176 | 176 | ||
| 177 | @memcpy(dst_cast, src_cast, len); | 177 | @memcpy(dst_cast[0..len], src_cast); |
| 178 | return dst; | 178 | return dst; |
| 179 | } | 179 | } |
| 180 | 180 |
src/Air.zig+11-8| ... | @@ -632,17 +632,20 @@ pub const Inst = struct { | ... | @@ -632,17 +632,20 @@ pub const Inst = struct { |
| 632 | /// Uses the `pl_op` field with `pred` as operand, and payload `Bin`. | 632 | /// Uses the `pl_op` field with `pred` as operand, and payload `Bin`. |
| 633 | select, | 633 | select, |
| 634 | 634 | ||
| 635 | /// Given dest ptr, value, and len, set all elements at dest to value. | 635 | /// Given dest pointer and value, set all elements at dest to value. |
| 636 | /// Dest pointer is either a slice or a pointer to array. | ||
| 637 | /// The element type may be any type, and the slice may have any alignment. | ||
| 636 | /// Result type is always void. | 638 | /// Result type is always void. |
| 637 | /// Uses the `pl_op` field. Operand is the dest ptr. Payload is `Bin`. `lhs` is the | 639 | /// Uses the `bin_op` field. LHS is the dest slice. RHS is the element value. |
| 638 | /// value, `rhs` is the length. | ||
| 639 | /// The element type may be any type, not just u8. | ||
| 640 | memset, | 640 | memset, |
| 641 | /// Given dest ptr, src ptr, and len, copy len elements from src to dest. | 641 | /// Given dest pointer and source pointer, copy elements from source to dest. |
| 642 | /// Dest pointer is either a slice or a pointer to array. | ||
| 643 | /// The dest element type may be any type. | ||
| 644 | /// Source pointer must have same element type as dest element type. | ||
| 645 | /// Dest slice may have any alignment; source pointer may have any alignment. | ||
| 646 | /// The two memory regions must not overlap. | ||
| 642 | /// Result type is always void. | 647 | /// Result type is always void. |
| 643 | /// Uses the `pl_op` field. Operand is the dest ptr. Payload is `Bin`. `lhs` is the | 648 | /// Uses the `bin_op` field. LHS is the dest slice. RHS is the source pointer. |
| 644 | /// src ptr, `rhs` is the length. | ||
| 645 | /// The element type may be any type, not just u8. | ||
| 646 | memcpy, | 649 | memcpy, |
| 647 | 650 | ||
| 648 | /// Uses the `ty_pl` field with payload `Cmpxchg`. | 651 | /// Uses the `ty_pl` field with payload `Cmpxchg`. |
src/AstGen.zig+6-8| ... | @@ -8453,18 +8453,16 @@ fn builtinCall( | ... | @@ -8453,18 +8453,16 @@ fn builtinCall( |
| 8453 | return rvalue(gz, ri, result, node); | 8453 | return rvalue(gz, ri, result, node); |
| 8454 | }, | 8454 | }, |
| 8455 | .memcpy => { | 8455 | .memcpy => { |
| 8456 | _ = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{ | 8456 | _ = try gz.addPlNode(.memcpy, node, Zir.Inst.Bin{ |
| 8457 | .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), | 8457 | .lhs = try expr(gz, scope, .{ .rl = .none }, params[0]), |
| 8458 | .source = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_const_u8_type } }, params[1]), | 8458 | .rhs = try expr(gz, scope, .{ .rl = .ref }, params[1]), |
| 8459 | .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), | ||
| 8460 | }); | 8459 | }); |
| 8461 | return rvalue(gz, ri, .void_value, node); | 8460 | return rvalue(gz, ri, .void_value, node); |
| 8462 | }, | 8461 | }, |
| 8463 | .memset => { | 8462 | .memset => { |
| 8464 | _ = try gz.addPlNode(.memset, node, Zir.Inst.Memset{ | 8463 | _ = try gz.addPlNode(.memset, node, Zir.Inst.Bin{ |
| 8465 | .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), | 8464 | .lhs = try expr(gz, scope, .{ .rl = .none }, params[0]), |
| 8466 | .byte = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u8_type } }, params[1]), | 8465 | .rhs = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8467 | .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), | ||
| 8468 | }); | 8466 | }); |
| 8469 | return rvalue(gz, ri, .void_value, node); | 8467 | return rvalue(gz, ri, .void_value, node); |
| 8470 | }, | 8468 | }, |
src/BuiltinFn.zig+2-2| ... | @@ -615,14 +615,14 @@ pub const list = list: { | ... | @@ -615,14 +615,14 @@ pub const list = list: { |
| 615 | "@memcpy", | 615 | "@memcpy", |
| 616 | .{ | 616 | .{ |
| 617 | .tag = .memcpy, | 617 | .tag = .memcpy, |
| 618 | .param_count = 3, | 618 | .param_count = 2, |
| 619 | }, | 619 | }, |
| 620 | }, | 620 | }, |
| 621 | .{ | 621 | .{ |
| 622 | "@memset", | 622 | "@memset", |
| 623 | .{ | 623 | .{ |
| 624 | .tag = .memset, | 624 | .tag = .memset, |
| 625 | .param_count = 3, | 625 | .param_count = 2, |
| 626 | }, | 626 | }, |
| 627 | }, | 627 | }, |
| 628 | .{ | 628 | .{ |
src/Liveness.zig+4-17| ... | @@ -304,6 +304,8 @@ pub fn categorizeOperand( | ... | @@ -304,6 +304,8 @@ pub fn categorizeOperand( |
| 304 | .atomic_store_release, | 304 | .atomic_store_release, |
| 305 | .atomic_store_seq_cst, | 305 | .atomic_store_seq_cst, |
| 306 | .set_union_tag, | 306 | .set_union_tag, |
| 307 | .memset, | ||
| 308 | .memcpy, | ||
| 307 | => { | 309 | => { |
| 308 | const o = air_datas[inst].bin_op; | 310 | const o = air_datas[inst].bin_op; |
| 309 | if (o.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write); | 311 | if (o.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write); |
| ... | @@ -597,16 +599,6 @@ pub fn categorizeOperand( | ... | @@ -597,16 +599,6 @@ pub fn categorizeOperand( |
| 597 | if (extra.operand == operand_ref) return matchOperandSmallIndex(l, inst, 1, .write); | 599 | if (extra.operand == operand_ref) return matchOperandSmallIndex(l, inst, 1, .write); |
| 598 | return .write; | 600 | return .write; |
| 599 | }, | 601 | }, |
| 600 | .memset, | ||
| 601 | .memcpy, | ||
| 602 | => { | ||
| 603 | const pl_op = air_datas[inst].pl_op; | ||
| 604 | const extra = air.extraData(Air.Bin, pl_op.payload).data; | ||
| 605 | if (pl_op.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write); | ||
| 606 | if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .write); | ||
| 607 | if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 2, .write); | ||
| 608 | return .write; | ||
| 609 | }, | ||
| 610 | 602 | ||
| 611 | .br => { | 603 | .br => { |
| 612 | const br = air_datas[inst].br; | 604 | const br = air_datas[inst].br; |
| ... | @@ -987,6 +979,8 @@ fn analyzeInst( | ... | @@ -987,6 +979,8 @@ fn analyzeInst( |
| 987 | .set_union_tag, | 979 | .set_union_tag, |
| 988 | .min, | 980 | .min, |
| 989 | .max, | 981 | .max, |
| 982 | .memset, | ||
| 983 | .memcpy, | ||
| 990 | => { | 984 | => { |
| 991 | const o = inst_datas[inst].bin_op; | 985 | const o = inst_datas[inst].bin_op; |
| 992 | return analyzeOperands(a, pass, data, inst, .{ o.lhs, o.rhs, .none }); | 986 | return analyzeOperands(a, pass, data, inst, .{ o.lhs, o.rhs, .none }); |
| ... | @@ -1234,13 +1228,6 @@ fn analyzeInst( | ... | @@ -1234,13 +1228,6 @@ fn analyzeInst( |
| 1234 | const extra = a.air.extraData(Air.AtomicRmw, pl_op.payload).data; | 1228 | const extra = a.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 1235 | return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.operand, .none }); | 1229 | return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.operand, .none }); |
| 1236 | }, | 1230 | }, |
| 1237 | .memset, | ||
| 1238 | .memcpy, | ||
| 1239 | => { | ||
| 1240 | const pl_op = inst_datas[inst].pl_op; | ||
| 1241 | const extra = a.air.extraData(Air.Bin, pl_op.payload).data; | ||
| 1242 | return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.lhs, extra.rhs }); | ||
| 1243 | }, | ||
| 1244 | 1231 | ||
| 1245 | .br => return analyzeInstBr(a, pass, data, inst), | 1232 | .br => return analyzeInstBr(a, pass, data, inst), |
| 1246 | 1233 |
src/Sema.zig+57-56| ... | @@ -9861,8 +9861,11 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -9861,8 +9861,11 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 9861 | const extra = sema.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data; | 9861 | const extra = sema.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data; |
| 9862 | const array_ptr = try sema.resolveInst(extra.lhs); | 9862 | const array_ptr = try sema.resolveInst(extra.lhs); |
| 9863 | const start = try sema.resolveInst(extra.start); | 9863 | const start = try sema.resolveInst(extra.start); |
| 9864 | const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node }; | ||
| 9865 | const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node }; | ||
| 9866 | const end_src: LazySrcLoc = .{ .node_offset_slice_end = inst_data.src_node }; | ||
| 9864 | 9867 | ||
| 9865 | return sema.analyzeSlice(block, src, array_ptr, start, .none, .none, .unneeded); | 9868 | return sema.analyzeSlice(block, src, array_ptr, start, .none, .none, .unneeded, ptr_src, start_src, end_src); |
| 9866 | } | 9869 | } |
| 9867 | 9870 | ||
| 9868 | fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 9871 | fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -9875,8 +9878,11 @@ fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -9875,8 +9878,11 @@ fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 9875 | const array_ptr = try sema.resolveInst(extra.lhs); | 9878 | const array_ptr = try sema.resolveInst(extra.lhs); |
| 9876 | const start = try sema.resolveInst(extra.start); | 9879 | const start = try sema.resolveInst(extra.start); |
| 9877 | const end = try sema.resolveInst(extra.end); | 9880 | const end = try sema.resolveInst(extra.end); |
| 9881 | const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node }; | ||
| 9882 | const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node }; | ||
| 9883 | const end_src: LazySrcLoc = .{ .node_offset_slice_end = inst_data.src_node }; | ||
| 9878 | 9884 | ||
| 9879 | return sema.analyzeSlice(block, src, array_ptr, start, end, .none, .unneeded); | 9885 | return sema.analyzeSlice(block, src, array_ptr, start, end, .none, .unneeded, ptr_src, start_src, end_src); |
| 9880 | } | 9886 | } |
| 9881 | 9887 | ||
| 9882 | fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 9888 | fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -9891,8 +9897,11 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -9891,8 +9897,11 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 9891 | const start = try sema.resolveInst(extra.start); | 9897 | const start = try sema.resolveInst(extra.start); |
| 9892 | const end = try sema.resolveInst(extra.end); | 9898 | const end = try sema.resolveInst(extra.end); |
| 9893 | const sentinel = try sema.resolveInst(extra.sentinel); | 9899 | const sentinel = try sema.resolveInst(extra.sentinel); |
| 9900 | const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node }; | ||
| 9901 | const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node }; | ||
| 9902 | const end_src: LazySrcLoc = .{ .node_offset_slice_end = inst_data.src_node }; | ||
| 9894 | 9903 | ||
| 9895 | return sema.analyzeSlice(block, src, array_ptr, start, end, sentinel, sentinel_src); | 9904 | return sema.analyzeSlice(block, src, array_ptr, start, end, sentinel, sentinel_src, ptr_src, start_src, end_src); |
| 9896 | } | 9905 | } |
| 9897 | 9906 | ||
| 9898 | fn zirSwitchCapture( | 9907 | fn zirSwitchCapture( |
| ... | @@ -20393,6 +20402,22 @@ fn checkPtrType( | ... | @@ -20393,6 +20402,22 @@ fn checkPtrType( |
| 20393 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)}); | 20402 | return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)}); |
| 20394 | } | 20403 | } |
| 20395 | 20404 | ||
| 20405 | fn checkSliceOrArrayType( | ||
| 20406 | sema: *Sema, | ||
| 20407 | block: *Block, | ||
| 20408 | ty_src: LazySrcLoc, | ||
| 20409 | ty: Type, | ||
| 20410 | ) CompileError!void { | ||
| 20411 | if (ty.zigTypeTag() == .Pointer) { | ||
| 20412 | switch (ty.ptrSize()) { | ||
| 20413 | .Slice => return, | ||
| 20414 | .One => if (ty.childType().zigTypeTag() == .Array) return, | ||
| 20415 | else => {}, | ||
| 20416 | } | ||
| 20417 | } | ||
| 20418 | return sema.fail(block, ty_src, "expected slice or array pointer; found '{}'", .{ty.fmt(sema.mod)}); | ||
| 20419 | } | ||
| 20420 | |||
| 20396 | fn checkVectorElemType( | 20421 | fn checkVectorElemType( |
| 20397 | sema: *Sema, | 20422 | sema: *Sema, |
| 20398 | block: *Block, | 20423 | block: *Block, |
| ... | @@ -21750,88 +21775,64 @@ fn analyzeMinMax( | ... | @@ -21750,88 +21775,64 @@ fn analyzeMinMax( |
| 21750 | 21775 | ||
| 21751 | fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 21776 | fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 21752 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 21777 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 21753 | const extra = sema.code.extraData(Zir.Inst.Memcpy, inst_data.payload_index).data; | 21778 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 21754 | const src = inst_data.src(); | 21779 | const src = inst_data.src(); |
| 21755 | const dest_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 21780 | const dest_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 21756 | const src_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 21781 | const src_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 21757 | const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; | 21782 | const dest_ptr = try sema.resolveInst(extra.lhs); |
| 21758 | const uncasted_dest_ptr = try sema.resolveInst(extra.dest); | 21783 | const src_ptr_ptr = try sema.resolveInst(extra.rhs); |
| 21759 | 21784 | const dest_ptr_ty = sema.typeOf(dest_ptr); | |
| 21760 | // TODO AstGen's coerced_ty cannot handle volatile here | 21785 | try checkSliceOrArrayType(sema, block, dest_src, dest_ptr_ty); |
| 21761 | var dest_ptr_info = Type.initTag(.manyptr_u8).ptrInfo().data; | 21786 | |
| 21762 | dest_ptr_info.@"volatile" = sema.typeOf(uncasted_dest_ptr).isVolatilePtr(); | 21787 | const dest_len = try sema.fieldVal(block, dest_src, dest_ptr, "len", dest_src); |
| 21763 | const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, dest_ptr_info); | 21788 | const src_ptr = try sema.analyzeSlice(block, src_src, src_ptr_ptr, .zero_usize, dest_len, .none, .unneeded, src_src, src_src, src_src); |
| 21764 | const dest_ptr = try sema.coerce(block, dest_ptr_ty, uncasted_dest_ptr, dest_src); | ||
| 21765 | |||
| 21766 | const uncasted_src_ptr = try sema.resolveInst(extra.source); | ||
| 21767 | var src_ptr_info = Type.initTag(.manyptr_const_u8).ptrInfo().data; | ||
| 21768 | src_ptr_info.@"volatile" = sema.typeOf(uncasted_src_ptr).isVolatilePtr(); | ||
| 21769 | const src_ptr_ty = try Type.ptr(sema.arena, sema.mod, src_ptr_info); | ||
| 21770 | const src_ptr = try sema.coerce(block, src_ptr_ty, uncasted_src_ptr, src_src); | ||
| 21771 | const len = try sema.coerce(block, Type.usize, try sema.resolveInst(extra.byte_count), len_src); | ||
| 21772 | 21789 | ||
| 21773 | const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: { | 21790 | const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: { |
| 21774 | if (!dest_ptr_val.isComptimeMutablePtr()) break :rs dest_src; | 21791 | if (!dest_ptr_val.isComptimeMutablePtr()) break :rs dest_src; |
| 21775 | if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |src_ptr_val| { | 21792 | if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |src_ptr_val| { |
| 21776 | if (!src_ptr_val.isComptimeMutablePtr()) break :rs src_src; | 21793 | if (!src_ptr_val.isComptimeMutablePtr()) break :rs src_src; |
| 21777 | if (try sema.resolveDefinedValue(block, len_src, len)) |len_val| { | 21794 | return sema.fail(block, src, "TODO: @memcpy at comptime", .{}); |
| 21778 | _ = len_val; | ||
| 21779 | return sema.fail(block, src, "TODO: Sema.zirMemcpy at comptime", .{}); | ||
| 21780 | } else break :rs len_src; | ||
| 21781 | } else break :rs src_src; | 21795 | } else break :rs src_src; |
| 21782 | } else dest_src; | 21796 | } else dest_src; |
| 21783 | 21797 | ||
| 21784 | try sema.requireRuntimeBlock(block, src, runtime_src); | 21798 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 21785 | _ = try block.addInst(.{ | 21799 | _ = try block.addInst(.{ |
| 21786 | .tag = .memcpy, | 21800 | .tag = .memcpy, |
| 21787 | .data = .{ .pl_op = .{ | 21801 | .data = .{ .bin_op = .{ |
| 21788 | .operand = dest_ptr, | 21802 | .lhs = dest_ptr, |
| 21789 | .payload = try sema.addExtra(Air.Bin{ | 21803 | .rhs = src_ptr, |
| 21790 | .lhs = src_ptr, | ||
| 21791 | .rhs = len, | ||
| 21792 | }), | ||
| 21793 | } }, | 21804 | } }, |
| 21794 | }); | 21805 | }); |
| 21795 | } | 21806 | } |
| 21796 | 21807 | ||
| 21797 | fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 21808 | fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 21798 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 21809 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 21799 | const extra = sema.code.extraData(Zir.Inst.Memset, inst_data.payload_index).data; | 21810 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 21800 | const src = inst_data.src(); | 21811 | const src = inst_data.src(); |
| 21801 | const dest_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 21812 | const dest_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 21802 | const value_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 21813 | const value_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 21803 | const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; | 21814 | const dest_ptr = try sema.resolveInst(extra.lhs); |
| 21804 | const uncasted_dest_ptr = try sema.resolveInst(extra.dest); | 21815 | const uncoerced_elem = try sema.resolveInst(extra.rhs); |
| 21816 | const dest_ptr_ty = sema.typeOf(dest_ptr); | ||
| 21817 | try checkSliceOrArrayType(sema, block, dest_src, dest_ptr_ty); | ||
| 21805 | 21818 | ||
| 21806 | // TODO AstGen's coerced_ty cannot handle volatile here | 21819 | const elem_ty = dest_ptr_ty.elemType2(); |
| 21807 | var ptr_info = Type.initTag(.manyptr_u8).ptrInfo().data; | 21820 | const elem = try sema.coerce(block, elem_ty, uncoerced_elem, value_src); |
| 21808 | ptr_info.@"volatile" = sema.typeOf(uncasted_dest_ptr).isVolatilePtr(); | ||
| 21809 | const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); | ||
| 21810 | const dest_ptr = try sema.coerce(block, dest_ptr_ty, uncasted_dest_ptr, dest_src); | ||
| 21811 | |||
| 21812 | const value = try sema.coerce(block, Type.u8, try sema.resolveInst(extra.byte), value_src); | ||
| 21813 | const len = try sema.coerce(block, Type.usize, try sema.resolveInst(extra.byte_count), len_src); | ||
| 21814 | 21821 | ||
| 21815 | const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: { | 21822 | const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: { |
| 21816 | if (!ptr_val.isComptimeMutablePtr()) break :rs dest_src; | 21823 | if (!ptr_val.isComptimeMutablePtr()) break :rs dest_src; |
| 21817 | if (try sema.resolveDefinedValue(block, len_src, len)) |len_val| { | 21824 | if (try sema.resolveMaybeUndefVal(elem)) |elem_val| { |
| 21818 | if (try sema.resolveMaybeUndefVal(value)) |val| { | 21825 | _ = elem_val; |
| 21819 | _ = len_val; | 21826 | return sema.fail(block, src, "TODO: @memset at comptime", .{}); |
| 21820 | _ = val; | 21827 | } else break :rs value_src; |
| 21821 | return sema.fail(block, src, "TODO: Sema.zirMemset at comptime", .{}); | ||
| 21822 | } else break :rs value_src; | ||
| 21823 | } else break :rs len_src; | ||
| 21824 | } else dest_src; | 21828 | } else dest_src; |
| 21825 | 21829 | ||
| 21826 | try sema.requireRuntimeBlock(block, src, runtime_src); | 21830 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 21827 | _ = try block.addInst(.{ | 21831 | _ = try block.addInst(.{ |
| 21828 | .tag = .memset, | 21832 | .tag = .memset, |
| 21829 | .data = .{ .pl_op = .{ | 21833 | .data = .{ .bin_op = .{ |
| 21830 | .operand = dest_ptr, | 21834 | .lhs = dest_ptr, |
| 21831 | .payload = try sema.addExtra(Air.Bin{ | 21835 | .rhs = elem, |
| 21832 | .lhs = value, | ||
| 21833 | .rhs = len, | ||
| 21834 | }), | ||
| 21835 | } }, | 21836 | } }, |
| 21836 | }); | 21837 | }); |
| 21837 | } | 21838 | } |
| ... | @@ -28753,10 +28754,10 @@ fn analyzeSlice( | ... | @@ -28753,10 +28754,10 @@ fn analyzeSlice( |
| 28753 | uncasted_end_opt: Air.Inst.Ref, | 28754 | uncasted_end_opt: Air.Inst.Ref, |
| 28754 | sentinel_opt: Air.Inst.Ref, | 28755 | sentinel_opt: Air.Inst.Ref, |
| 28755 | sentinel_src: LazySrcLoc, | 28756 | sentinel_src: LazySrcLoc, |
| 28757 | ptr_src: LazySrcLoc, | ||
| 28758 | start_src: LazySrcLoc, | ||
| 28759 | end_src: LazySrcLoc, | ||
| 28756 | ) CompileError!Air.Inst.Ref { | 28760 | ) CompileError!Air.Inst.Ref { |
| 28757 | const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = src.node_offset.x }; | ||
| 28758 | const start_src: LazySrcLoc = .{ .node_offset_slice_start = src.node_offset.x }; | ||
| 28759 | const end_src: LazySrcLoc = .{ .node_offset_slice_end = src.node_offset.x }; | ||
| 28760 | // Slice expressions can operate on a variable whose type is an array. This requires | 28761 | // Slice expressions can operate on a variable whose type is an array. This requires |
| 28761 | // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer. | 28762 | // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer. |
| 28762 | const ptr_ptr_ty = sema.typeOf(ptr_ptr); | 28763 | const ptr_ptr_ty = sema.typeOf(ptr_ptr); |
src/Zir.zig+2-14| ... | @@ -922,10 +922,10 @@ pub const Inst = struct { | ... | @@ -922,10 +922,10 @@ pub const Inst = struct { |
| 922 | /// Uses the `pl_node` union field with payload `FieldParentPtr`. | 922 | /// Uses the `pl_node` union field with payload `FieldParentPtr`. |
| 923 | field_parent_ptr, | 923 | field_parent_ptr, |
| 924 | /// Implements the `@memcpy` builtin. | 924 | /// Implements the `@memcpy` builtin. |
| 925 | /// Uses the `pl_node` union field with payload `Memcpy`. | 925 | /// Uses the `pl_node` union field with payload `Bin`. |
| 926 | memcpy, | 926 | memcpy, |
| 927 | /// Implements the `@memset` builtin. | 927 | /// Implements the `@memset` builtin. |
| 928 | /// Uses the `pl_node` union field with payload `Memset`. | 928 | /// Uses the `pl_node` union field with payload `Bin`. |
| 929 | memset, | 929 | memset, |
| 930 | /// Implements the `@min` builtin. | 930 | /// Implements the `@min` builtin. |
| 931 | /// Uses the `pl_node` union field with payload `Bin` | 931 | /// Uses the `pl_node` union field with payload `Bin` |
| ... | @@ -3501,18 +3501,6 @@ pub const Inst = struct { | ... | @@ -3501,18 +3501,6 @@ pub const Inst = struct { |
| 3501 | field_ptr: Ref, | 3501 | field_ptr: Ref, |
| 3502 | }; | 3502 | }; |
| 3503 | 3503 | ||
| 3504 | pub const Memcpy = struct { | ||
| 3505 | dest: Ref, | ||
| 3506 | source: Ref, | ||
| 3507 | byte_count: Ref, | ||
| 3508 | }; | ||
| 3509 | |||
| 3510 | pub const Memset = struct { | ||
| 3511 | dest: Ref, | ||
| 3512 | byte: Ref, | ||
| 3513 | byte_count: Ref, | ||
| 3514 | }; | ||
| 3515 | |||
| 3516 | pub const Shuffle = struct { | 3504 | pub const Shuffle = struct { |
| 3517 | elem_type: Ref, | 3505 | elem_type: Ref, |
| 3518 | a: Ref, | 3506 | a: Ref, |
src/codegen/llvm.zig+54-17| ... | @@ -5776,6 +5776,36 @@ pub const FuncGen = struct { | ... | @@ -5776,6 +5776,36 @@ pub const FuncGen = struct { |
| 5776 | return result; | 5776 | return result; |
| 5777 | } | 5777 | } |
| 5778 | 5778 | ||
| 5779 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value { | ||
| 5780 | switch (ty.ptrSize()) { | ||
| 5781 | .Slice => return fg.builder.buildExtractValue(ptr, 0, ""), | ||
| 5782 | .One => return ptr, | ||
| 5783 | .Many, .C => unreachable, | ||
| 5784 | } | ||
| 5785 | } | ||
| 5786 | |||
| 5787 | fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value { | ||
| 5788 | const target = fg.dg.module.getTarget(); | ||
| 5789 | const llvm_usize_ty = fg.context.intType(target.cpu.arch.ptrBitWidth()); | ||
| 5790 | switch (ty.ptrSize()) { | ||
| 5791 | .Slice => { | ||
| 5792 | const len = fg.builder.buildExtractValue(ptr, 1, ""); | ||
| 5793 | const elem_ty = ty.childType(); | ||
| 5794 | const abi_size = elem_ty.abiSize(target); | ||
| 5795 | if (abi_size == 1) return len; | ||
| 5796 | const abi_size_llvm_val = llvm_usize_ty.constInt(abi_size, .False); | ||
| 5797 | return fg.builder.buildMul(len, abi_size_llvm_val, ""); | ||
| 5798 | }, | ||
| 5799 | .One => { | ||
| 5800 | const array_ty = ty.childType(); | ||
| 5801 | const elem_ty = array_ty.childType(); | ||
| 5802 | const abi_size = elem_ty.abiSize(target); | ||
| 5803 | return llvm_usize_ty.constInt(array_ty.arrayLen() * abi_size, .False); | ||
| 5804 | }, | ||
| 5805 | .Many, .C => unreachable, | ||
| 5806 | } | ||
| 5807 | } | ||
| 5808 | |||
| 5779 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value { | 5809 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value { |
| 5780 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5810 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5781 | const operand = try self.resolveInst(ty_op.operand); | 5811 | const operand = try self.resolveInst(ty_op.operand); |
| ... | @@ -8374,18 +8404,24 @@ pub const FuncGen = struct { | ... | @@ -8374,18 +8404,24 @@ pub const FuncGen = struct { |
| 8374 | } | 8404 | } |
| 8375 | 8405 | ||
| 8376 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 8406 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8377 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 8407 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 8378 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 8408 | const dest_slice = try self.resolveInst(bin_op.lhs); |
| 8379 | const dest_ptr = try self.resolveInst(pl_op.operand); | 8409 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 8380 | const ptr_ty = self.air.typeOf(pl_op.operand); | 8410 | const value = try self.resolveInst(bin_op.rhs); |
| 8381 | const value = try self.resolveInst(extra.lhs); | 8411 | const elem_ty = self.air.typeOf(bin_op.rhs); |
| 8382 | const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false; | ||
| 8383 | const len = try self.resolveInst(extra.rhs); | ||
| 8384 | const u8_llvm_ty = self.context.intType(8); | ||
| 8385 | const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value; | ||
| 8386 | const target = self.dg.module.getTarget(); | 8412 | const target = self.dg.module.getTarget(); |
| 8413 | const val_is_undef = if (self.air.value(bin_op.rhs)) |val| val.isUndefDeep() else false; | ||
| 8414 | const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty); | ||
| 8415 | const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty); | ||
| 8416 | const u8_llvm_ty = self.context.intType(8); | ||
| 8417 | const fill_byte = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else b: { | ||
| 8418 | if (elem_ty.abiSize(target) != 1) { | ||
| 8419 | return self.dg.todo("implement @memset for non-byte-sized element type", .{}); | ||
| 8420 | } | ||
| 8421 | break :b self.builder.buildBitCast(value, u8_llvm_ty, ""); | ||
| 8422 | }; | ||
| 8387 | const dest_ptr_align = ptr_ty.ptrAlignment(target); | 8423 | const dest_ptr_align = ptr_ty.ptrAlignment(target); |
| 8388 | _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr()); | 8424 | _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr()); |
| 8389 | 8425 | ||
| 8390 | if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) { | 8426 | if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) { |
| 8391 | self.valgrindMarkUndef(dest_ptr, len); | 8427 | self.valgrindMarkUndef(dest_ptr, len); |
| ... | @@ -8394,13 +8430,14 @@ pub const FuncGen = struct { | ... | @@ -8394,13 +8430,14 @@ pub const FuncGen = struct { |
| 8394 | } | 8430 | } |
| 8395 | 8431 | ||
| 8396 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 8432 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8397 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 8433 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 8398 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 8434 | const dest_slice = try self.resolveInst(bin_op.lhs); |
| 8399 | const dest_ptr = try self.resolveInst(pl_op.operand); | 8435 | const dest_ptr_ty = self.air.typeOf(bin_op.lhs); |
| 8400 | const dest_ptr_ty = self.air.typeOf(pl_op.operand); | 8436 | const src_slice = try self.resolveInst(bin_op.rhs); |
| 8401 | const src_ptr = try self.resolveInst(extra.lhs); | 8437 | const src_ptr_ty = self.air.typeOf(bin_op.rhs); |
| 8402 | const src_ptr_ty = self.air.typeOf(extra.lhs); | 8438 | const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty); |
| 8403 | const len = try self.resolveInst(extra.rhs); | 8439 | const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty); |
| 8440 | const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty); | ||
| 8404 | const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr(); | 8441 | const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr(); |
| 8405 | const target = self.dg.module.getTarget(); | 8442 | const target = self.dg.module.getTarget(); |
| 8406 | _ = self.builder.buildMemCpy( | 8443 | _ = self.builder.buildMemCpy( |
src/print_air.zig+2-24| ... | @@ -169,6 +169,8 @@ const Writer = struct { | ... | @@ -169,6 +169,8 @@ const Writer = struct { |
| 169 | .cmp_gte_optimized, | 169 | .cmp_gte_optimized, |
| 170 | .cmp_gt_optimized, | 170 | .cmp_gt_optimized, |
| 171 | .cmp_neq_optimized, | 171 | .cmp_neq_optimized, |
| 172 | .memcpy, | ||
| 173 | .memset, | ||
| 172 | => try w.writeBinOp(s, inst), | 174 | => try w.writeBinOp(s, inst), |
| 173 | 175 | ||
| 174 | .is_null, | 176 | .is_null, |
| ... | @@ -315,8 +317,6 @@ const Writer = struct { | ... | @@ -315,8 +317,6 @@ const Writer = struct { |
| 315 | .atomic_store_release => try w.writeAtomicStore(s, inst, .Release), | 317 | .atomic_store_release => try w.writeAtomicStore(s, inst, .Release), |
| 316 | .atomic_store_seq_cst => try w.writeAtomicStore(s, inst, .SeqCst), | 318 | .atomic_store_seq_cst => try w.writeAtomicStore(s, inst, .SeqCst), |
| 317 | .atomic_rmw => try w.writeAtomicRmw(s, inst), | 319 | .atomic_rmw => try w.writeAtomicRmw(s, inst), |
| 318 | .memcpy => try w.writeMemcpy(s, inst), | ||
| 319 | .memset => try w.writeMemset(s, inst), | ||
| 320 | .field_parent_ptr => try w.writeFieldParentPtr(s, inst), | 320 | .field_parent_ptr => try w.writeFieldParentPtr(s, inst), |
| 321 | .wasm_memory_size => try w.writeWasmMemorySize(s, inst), | 321 | .wasm_memory_size => try w.writeWasmMemorySize(s, inst), |
| 322 | .wasm_memory_grow => try w.writeWasmMemoryGrow(s, inst), | 322 | .wasm_memory_grow => try w.writeWasmMemoryGrow(s, inst), |
| ... | @@ -591,17 +591,6 @@ const Writer = struct { | ... | @@ -591,17 +591,6 @@ const Writer = struct { |
| 591 | try s.print(", {s}, {s}", .{ @tagName(extra.op()), @tagName(extra.ordering()) }); | 591 | try s.print(", {s}, {s}", .{ @tagName(extra.op()), @tagName(extra.ordering()) }); |
| 592 | } | 592 | } |
| 593 | 593 | ||
| 594 | fn writeMemset(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | ||
| 595 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; | ||
| 596 | const extra = w.air.extraData(Air.Bin, pl_op.payload).data; | ||
| 597 | |||
| 598 | try w.writeOperand(s, inst, 0, pl_op.operand); | ||
| 599 | try s.writeAll(", "); | ||
| 600 | try w.writeOperand(s, inst, 1, extra.lhs); | ||
| 601 | try s.writeAll(", "); | ||
| 602 | try w.writeOperand(s, inst, 2, extra.rhs); | ||
| 603 | } | ||
| 604 | |||
| 605 | fn writeFieldParentPtr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 594 | fn writeFieldParentPtr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 606 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; | 595 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; |
| 607 | const extra = w.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 596 | const extra = w.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| ... | @@ -610,17 +599,6 @@ const Writer = struct { | ... | @@ -610,17 +599,6 @@ const Writer = struct { |
| 610 | try s.print(", {d}", .{extra.field_index}); | 599 | try s.print(", {d}", .{extra.field_index}); |
| 611 | } | 600 | } |
| 612 | 601 | ||
| 613 | fn writeMemcpy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | ||
| 614 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; | ||
| 615 | const extra = w.air.extraData(Air.Bin, pl_op.payload).data; | ||
| 616 | |||
| 617 | try w.writeOperand(s, inst, 0, pl_op.operand); | ||
| 618 | try s.writeAll(", "); | ||
| 619 | try w.writeOperand(s, inst, 1, extra.lhs); | ||
| 620 | try s.writeAll(", "); | ||
| 621 | try w.writeOperand(s, inst, 2, extra.rhs); | ||
| 622 | } | ||
| 623 | |||
| 624 | fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 602 | fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 625 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; | 603 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; |
| 626 | const val = w.air.values[ty_pl.payload]; | 604 | const val = w.air.values[ty_pl.payload]; |
src/print_zir.zig+2-28| ... | @@ -277,8 +277,6 @@ const Writer = struct { | ... | @@ -277,8 +277,6 @@ const Writer = struct { |
| 277 | .atomic_load => try self.writeAtomicLoad(stream, inst), | 277 | .atomic_load => try self.writeAtomicLoad(stream, inst), |
| 278 | .atomic_store => try self.writeAtomicStore(stream, inst), | 278 | .atomic_store => try self.writeAtomicStore(stream, inst), |
| 279 | .atomic_rmw => try self.writeAtomicRmw(stream, inst), | 279 | .atomic_rmw => try self.writeAtomicRmw(stream, inst), |
| 280 | .memcpy => try self.writeMemcpy(stream, inst), | ||
| 281 | .memset => try self.writeMemset(stream, inst), | ||
| 282 | .shuffle => try self.writeShuffle(stream, inst), | 280 | .shuffle => try self.writeShuffle(stream, inst), |
| 283 | .mul_add => try self.writeMulAdd(stream, inst), | 281 | .mul_add => try self.writeMulAdd(stream, inst), |
| 284 | .field_parent_ptr => try self.writeFieldParentPtr(stream, inst), | 282 | .field_parent_ptr => try self.writeFieldParentPtr(stream, inst), |
| ... | @@ -346,6 +344,8 @@ const Writer = struct { | ... | @@ -346,6 +344,8 @@ const Writer = struct { |
| 346 | .vector_type, | 344 | .vector_type, |
| 347 | .max, | 345 | .max, |
| 348 | .min, | 346 | .min, |
| 347 | .memcpy, | ||
| 348 | .memset, | ||
| 349 | .elem_ptr_node, | 349 | .elem_ptr_node, |
| 350 | .elem_val_node, | 350 | .elem_val_node, |
| 351 | .elem_ptr, | 351 | .elem_ptr, |
| ... | @@ -1000,32 +1000,6 @@ const Writer = struct { | ... | @@ -1000,32 +1000,6 @@ const Writer = struct { |
| 1000 | try self.writeSrc(stream, inst_data.src()); | 1000 | try self.writeSrc(stream, inst_data.src()); |
| 1001 | } | 1001 | } |
| 1002 | 1002 | ||
| 1003 | fn writeMemcpy(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { | ||
| 1004 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | ||
| 1005 | const extra = self.code.extraData(Zir.Inst.Memcpy, inst_data.payload_index).data; | ||
| 1006 | |||
| 1007 | try self.writeInstRef(stream, extra.dest); | ||
| 1008 | try stream.writeAll(", "); | ||
| 1009 | try self.writeInstRef(stream, extra.source); | ||
| 1010 | try stream.writeAll(", "); | ||
| 1011 | try self.writeInstRef(stream, extra.byte_count); | ||
| 1012 | try stream.writeAll(") "); | ||
| 1013 | try self.writeSrc(stream, inst_data.src()); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | fn writeMemset(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { | ||
| 1017 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | ||
| 1018 | const extra = self.code.extraData(Zir.Inst.Memset, inst_data.payload_index).data; | ||
| 1019 | |||
| 1020 | try self.writeInstRef(stream, extra.dest); | ||
| 1021 | try stream.writeAll(", "); | ||
| 1022 | try self.writeInstRef(stream, extra.byte); | ||
| 1023 | try stream.writeAll(", "); | ||
| 1024 | try self.writeInstRef(stream, extra.byte_count); | ||
| 1025 | try stream.writeAll(") "); | ||
| 1026 | try self.writeSrc(stream, inst_data.src()); | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | fn writeStructInitAnon(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { | 1003 | fn writeStructInitAnon(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { |
| 1030 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | 1004 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 1031 | const extra = self.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index); | 1005 | const extra = self.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index); |
test/behavior/basic.zig+2-2| ... | @@ -367,8 +367,8 @@ fn testMemcpyMemset() !void { | ... | @@ -367,8 +367,8 @@ fn testMemcpyMemset() !void { |
| 367 | var foo: [20]u8 = undefined; | 367 | var foo: [20]u8 = undefined; |
| 368 | var bar: [20]u8 = undefined; | 368 | var bar: [20]u8 = undefined; |
| 369 | 369 | ||
| 370 | @memset(&foo, 'A', foo.len); | 370 | @memset(&foo, 'A'); |
| 371 | @memcpy(&bar, &foo, bar.len); | 371 | @memcpy(&bar, &foo); |
| 372 | 372 | ||
| 373 | try expect(bar[0] == 'A'); | 373 | try expect(bar[0] == 'A'); |
| 374 | try expect(bar[11] == 'A'); | 374 | try expect(bar[11] == 'A'); |
test/behavior/bugs/718.zig+1-1| ... | @@ -14,7 +14,7 @@ test "zero keys with @memset" { | ... | @@ -14,7 +14,7 @@ test "zero keys with @memset" { |
| 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 15 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 16 | 16 | ||
| 17 | @memset(@ptrCast([*]u8, &keys), 0, @sizeOf(@TypeOf(keys))); | 17 | @memset(@ptrCast([*]u8, &keys)[0..@sizeOf(@TypeOf(keys))], 0); |
| 18 | try expect(!keys.up); | 18 | try expect(!keys.up); |
| 19 | try expect(!keys.down); | 19 | try expect(!keys.down); |
| 20 | try expect(!keys.left); | 20 | try expect(!keys.left); |
test/behavior/struct.zig+2-2| ... | @@ -91,7 +91,7 @@ test "structs" { | ... | @@ -91,7 +91,7 @@ test "structs" { |
| 91 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 91 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 92 | 92 | ||
| 93 | var foo: StructFoo = undefined; | 93 | var foo: StructFoo = undefined; |
| 94 | @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo)); | 94 | @memset(@ptrCast([*]u8, &foo)[0..@sizeOf(StructFoo)], 0); |
| 95 | foo.a += 1; | 95 | foo.a += 1; |
| 96 | foo.b = foo.a == 1; | 96 | foo.b = foo.a == 1; |
| 97 | try testFoo(foo); | 97 | try testFoo(foo); |
| ... | @@ -498,7 +498,7 @@ test "packed struct fields are ordered from LSB to MSB" { | ... | @@ -498,7 +498,7 @@ test "packed struct fields are ordered from LSB to MSB" { |
| 498 | 498 | ||
| 499 | var all: u64 = 0x7765443322221111; | 499 | var all: u64 = 0x7765443322221111; |
| 500 | var bytes: [8]u8 align(@alignOf(Bitfields)) = undefined; | 500 | var bytes: [8]u8 align(@alignOf(Bitfields)) = undefined; |
| 501 | @memcpy(&bytes, @ptrCast([*]u8, &all), 8); | 501 | @memcpy(bytes[0..8], @ptrCast([*]u8, &all)); |
| 502 | var bitfields = @ptrCast(*Bitfields, &bytes).*; | 502 | var bitfields = @ptrCast(*Bitfields, &bytes).*; |
| 503 | 503 | ||
| 504 | try expect(bitfields.f1 == 0x1111); | 504 | try expect(bitfields.f1 == 0x1111); |