| author | |
| committer | |
| log | 4e78836d29260e915e767bc907ff7ba6c652ef5f |
| tree | 5006310b522813a4729d4883b6f1557a3ce81719 |
| parent | 898ca824585e78306bb0137dbae1fbf859b762b6 |
8 files changed, 478 insertions(+), 1 deletions(-)
test/behavior.zig+1| ... | ... | @@ -55,6 +55,7 @@ test { |
| 55 | 55 | _ = @import("behavior/member_func.zig"); |
| 56 | 56 | _ = @import("behavior/memcpy.zig"); |
| 57 | 57 | _ = @import("behavior/memset.zig"); |
| 58 | _ = @import("behavior/memmove.zig"); | |
| 58 | 59 | _ = @import("behavior/merge_error_sets.zig"); |
| 59 | 60 | _ = @import("behavior/muladd.zig"); |
| 60 | 61 | _ = @import("behavior/multiple_externs_with_conflicting_types.zig"); |
test/behavior/builtin_functions_returning_void_or_noreturn.zig+2| ... | ... | @@ -6,6 +6,7 @@ var x: u8 = 1; |
| 6 | 6 | |
| 7 | 7 | // This excludes builtin functions that return void or noreturn that cannot be tested. |
| 8 | 8 | test { |
| 9 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 9 | 10 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 10 | 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 11 | 12 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -17,6 +18,7 @@ test { |
| 17 | 18 | try testing.expectEqual(void, @TypeOf(@breakpoint())); |
| 18 | 19 | try testing.expectEqual({}, @export(&x, .{ .name = "x" })); |
| 19 | 20 | try testing.expectEqual({}, @memcpy(@as([*]u8, @ptrFromInt(1))[0..0], @as([*]u8, @ptrFromInt(1))[0..0])); |
| 21 | try testing.expectEqual({}, @memmove(@as([*]u8, @ptrFromInt(1))[0..0], @as([*]u8, @ptrFromInt(1))[0..0])); | |
| 20 | 22 | try testing.expectEqual({}, @memset(@as([*]u8, @ptrFromInt(1))[0..0], undefined)); |
| 21 | 23 | try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {})); |
| 22 | 24 | try testing.expectEqual({}, @prefetch(&val, .{})); |
test/behavior/memmove.zig created+183| ... | ... | @@ -0,0 +1,183 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | test "memmove and memset intrinsics" { | |
| 6 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 8 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 9 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 10 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 11 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 12 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 13 | ||
| 14 | try testMemmoveMemset(); | |
| 15 | try comptime testMemmoveMemset(); | |
| 16 | } | |
| 17 | ||
| 18 | fn testMemmoveMemset() !void { | |
| 19 | var foo: [20]u8 = undefined; | |
| 20 | ||
| 21 | @memset(foo[0..10], 'A'); | |
| 22 | @memset(foo[10..20], 'B'); | |
| 23 | ||
| 24 | try expect(foo[0] == 'A'); | |
| 25 | try expect(foo[11] == 'B'); | |
| 26 | try expect(foo[19] == 'B'); | |
| 27 | ||
| 28 | @memmove(foo[10..20], foo[0..10]); | |
| 29 | ||
| 30 | try expect(foo[0] == 'A'); | |
| 31 | try expect(foo[11] == 'A'); | |
| 32 | try expect(foo[19] == 'A'); | |
| 33 | } | |
| 34 | ||
| 35 | test "@memmove with both operands single-ptr-to-array, one is null-terminated" { | |
| 36 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 37 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 38 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 39 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | |
| 40 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 41 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 42 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 43 | ||
| 44 | try testMemmoveBothSinglePtrArrayOneIsNullTerminated(); | |
| 45 | try comptime testMemmoveBothSinglePtrArrayOneIsNullTerminated(); | |
| 46 | } | |
| 47 | ||
| 48 | fn testMemmoveBothSinglePtrArrayOneIsNullTerminated() !void { | |
| 49 | var buf: [100]u8 = undefined; | |
| 50 | const suffix = "hello"; | |
| 51 | @memmove(buf[buf.len - suffix.len ..], suffix); | |
| 52 | try expect(buf[95] == 'h'); | |
| 53 | try expect(buf[96] == 'e'); | |
| 54 | try expect(buf[97] == 'l'); | |
| 55 | try expect(buf[98] == 'l'); | |
| 56 | try expect(buf[99] == 'o'); | |
| 57 | ||
| 58 | const start = buf.len - suffix.len - 3; | |
| 59 | const end = start + suffix.len; | |
| 60 | @memmove(buf[start..end], buf[buf.len - suffix.len ..]); | |
| 61 | try expect(buf[92] == 'h'); | |
| 62 | try expect(buf[93] == 'e'); | |
| 63 | try expect(buf[94] == 'l'); | |
| 64 | try expect(buf[95] == 'l'); | |
| 65 | try expect(buf[96] == 'o'); | |
| 66 | try expect(buf[97] == 'l'); | |
| 67 | try expect(buf[98] == 'l'); | |
| 68 | try expect(buf[99] == 'o'); | |
| 69 | ||
| 70 | @memmove(buf[start + 2 .. end + 2], buf[start..end]); | |
| 71 | try expect(buf[92] == 'h'); | |
| 72 | try expect(buf[93] == 'e'); | |
| 73 | try expect(buf[94] == 'h'); | |
| 74 | try expect(buf[95] == 'e'); | |
| 75 | try expect(buf[96] == 'l'); | |
| 76 | try expect(buf[97] == 'l'); | |
| 77 | try expect(buf[98] == 'o'); | |
| 78 | try expect(buf[99] == 'o'); | |
| 79 | } | |
| 80 | ||
| 81 | test "@memmove dest many pointer" { | |
| 82 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 83 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 84 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 85 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | |
| 86 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 87 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 88 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 89 | ||
| 90 | try testMemmoveDestManyPtr(); | |
| 91 | try comptime testMemmoveDestManyPtr(); | |
| 92 | } | |
| 93 | ||
| 94 | fn testMemmoveDestManyPtr() !void { | |
| 95 | var str = "hello".*; | |
| 96 | var buf: [8]u8 = undefined; | |
| 97 | var len: usize = 5; | |
| 98 | _ = &len; | |
| 99 | @memmove(@as([*]u8, @ptrCast(&buf)), @as([*]const u8, @ptrCast(&str))[0..len]); | |
| 100 | try expect(buf[0] == 'h'); | |
| 101 | try expect(buf[1] == 'e'); | |
| 102 | try expect(buf[2] == 'l'); | |
| 103 | try expect(buf[3] == 'l'); | |
| 104 | try expect(buf[4] == 'o'); | |
| 105 | @memmove(buf[3..].ptr, buf[0..len]); | |
| 106 | try expect(buf[0] == 'h'); | |
| 107 | try expect(buf[1] == 'e'); | |
| 108 | try expect(buf[2] == 'l'); | |
| 109 | try expect(buf[3] == 'h'); | |
| 110 | try expect(buf[4] == 'e'); | |
| 111 | try expect(buf[5] == 'l'); | |
| 112 | try expect(buf[6] == 'l'); | |
| 113 | try expect(buf[7] == 'o'); | |
| 114 | @memmove(buf[2..7].ptr, buf[3 .. len + 3]); | |
| 115 | try expect(buf[0] == 'h'); | |
| 116 | try expect(buf[1] == 'e'); | |
| 117 | try expect(buf[2] == 'h'); | |
| 118 | try expect(buf[3] == 'e'); | |
| 119 | try expect(buf[4] == 'l'); | |
| 120 | try expect(buf[5] == 'l'); | |
| 121 | try expect(buf[6] == 'o'); | |
| 122 | try expect(buf[7] == 'o'); | |
| 123 | } | |
| 124 | ||
| 125 | test "@memmove slice" { | |
| 126 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 127 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 128 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 129 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | |
| 130 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 131 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 132 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 133 | ||
| 134 | try testMemmoveSlice(); | |
| 135 | try comptime testMemmoveSlice(); | |
| 136 | } | |
| 137 | ||
| 138 | fn testMemmoveSlice() !void { | |
| 139 | var buf: [8]u8 = undefined; | |
| 140 | const dst1: []u8 = buf[0..5]; | |
| 141 | const dst2: []u8 = buf[3..8]; | |
| 142 | const dst3: []u8 = buf[2..7]; | |
| 143 | const src: []const u8 = "hello"; | |
| 144 | @memmove(dst1, src); | |
| 145 | try expect(buf[0] == 'h'); | |
| 146 | try expect(buf[1] == 'e'); | |
| 147 | try expect(buf[2] == 'l'); | |
| 148 | try expect(buf[3] == 'l'); | |
| 149 | try expect(buf[4] == 'o'); | |
| 150 | @memmove(dst2, dst1); | |
| 151 | try expect(buf[0] == 'h'); | |
| 152 | try expect(buf[1] == 'e'); | |
| 153 | try expect(buf[2] == 'l'); | |
| 154 | try expect(buf[3] == 'h'); | |
| 155 | try expect(buf[4] == 'e'); | |
| 156 | try expect(buf[5] == 'l'); | |
| 157 | try expect(buf[6] == 'l'); | |
| 158 | try expect(buf[7] == 'o'); | |
| 159 | @memmove(dst3, dst2); | |
| 160 | try expect(buf[0] == 'h'); | |
| 161 | try expect(buf[1] == 'e'); | |
| 162 | try expect(buf[2] == 'h'); | |
| 163 | try expect(buf[3] == 'e'); | |
| 164 | try expect(buf[4] == 'l'); | |
| 165 | try expect(buf[5] == 'l'); | |
| 166 | try expect(buf[6] == 'o'); | |
| 167 | try expect(buf[7] == 'o'); | |
| 168 | } | |
| 169 | ||
| 170 | comptime { | |
| 171 | const S = struct { | |
| 172 | buffer: [8]u8 = undefined, | |
| 173 | fn set(self: *@This(), items: []const u8) void { | |
| 174 | @memmove(self.buffer[0..items.len], items); | |
| 175 | @memmove(self.buffer[3..], self.buffer[0..items.len]); | |
| 176 | @memmove(self.buffer[2 .. 2 + items.len], self.buffer[3..]); | |
| 177 | } | |
| 178 | }; | |
| 179 | ||
| 180 | var s = S{}; | |
| 181 | s.set("hello"); | |
| 182 | if (!std.mem.eql(u8, s.buffer[0..8], "hehelloo")) @compileError("bad"); | |
| 183 | } |
test/cases/compile_errors/@memmove_type_mismatch.zig created+218| ... | ... | @@ -0,0 +1,218 @@ |
| 1 | export fn foo() void { | |
| 2 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 3 | const dest: []u8 = &buf; | |
| 4 | const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 5 | ||
| 6 | @memmove(dest, src); | |
| 7 | } | |
| 8 | ||
| 9 | export fn bar() void { | |
| 10 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 11 | const dest: []u8 = &buf; | |
| 12 | const src: *align(1) [8]u16 = @ptrCast(&buf); | |
| 13 | ||
| 14 | @memmove(dest, src); | |
| 15 | } | |
| 16 | ||
| 17 | export fn baz() void { | |
| 18 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 19 | const dest: []u8 = &buf; | |
| 20 | const src: [*]align(1) u16 = @ptrCast(&buf); | |
| 21 | ||
| 22 | @memmove(dest, src); | |
| 23 | } | |
| 24 | ||
| 25 | export fn qux() void { | |
| 26 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 27 | const dest: *[8]u8 = &buf; | |
| 28 | const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 29 | ||
| 30 | @memmove(dest, src); | |
| 31 | } | |
| 32 | ||
| 33 | export fn quux() void { | |
| 34 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 35 | const dest: *[8]u8 = &buf; | |
| 36 | const src: *align(1) [8]u16 = @ptrCast(&buf); | |
| 37 | ||
| 38 | @memmove(dest, src); | |
| 39 | } | |
| 40 | ||
| 41 | export fn quuux() void { | |
| 42 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 43 | const dest: *[8]u8 = &buf; | |
| 44 | const src: [*]align(1) u16 = @ptrCast(&buf); | |
| 45 | ||
| 46 | @memmove(dest, src); | |
| 47 | } | |
| 48 | ||
| 49 | export fn foo2() void { | |
| 50 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 51 | const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 52 | const src: []u8 = &buf; | |
| 53 | ||
| 54 | @memmove(dest, src); | |
| 55 | } | |
| 56 | ||
| 57 | export fn bar2() void { | |
| 58 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 59 | const dest: *align(1) [8]u16 = @ptrCast(&buf); | |
| 60 | const src: []u8 = &buf; | |
| 61 | ||
| 62 | @memmove(dest, src); | |
| 63 | } | |
| 64 | ||
| 65 | export fn baz2() void { | |
| 66 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 67 | const dest: [*]align(1) u16 = @ptrCast(&buf); | |
| 68 | const src: []u8 = &buf; | |
| 69 | ||
| 70 | @memmove(dest, src); | |
| 71 | } | |
| 72 | ||
| 73 | export fn qux2() void { | |
| 74 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 75 | const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 76 | const src: *[8]u8 = &buf; | |
| 77 | ||
| 78 | @memmove(dest, src); | |
| 79 | } | |
| 80 | ||
| 81 | export fn quux2() void { | |
| 82 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 83 | const dest: *align(1) [8]u16 = @ptrCast(&buf); | |
| 84 | const src: *[8]u8 = &buf; | |
| 85 | ||
| 86 | @memmove(dest, src); | |
| 87 | } | |
| 88 | ||
| 89 | export fn quuux2() void { | |
| 90 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 91 | const dest: [*]align(1) u16 = @ptrCast(&buf); | |
| 92 | const src: *[8]u8 = &buf; | |
| 93 | ||
| 94 | @memmove(dest, src); | |
| 95 | } | |
| 96 | ||
| 97 | comptime { | |
| 98 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 99 | const dest: []u8 = &buf; | |
| 100 | const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 101 | @memmove(dest, src); | |
| 102 | } | |
| 103 | ||
| 104 | comptime { | |
| 105 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 106 | const dest: []u8 = &buf; | |
| 107 | const src: *align(1) [8]u16 = @ptrCast(&buf); | |
| 108 | @memmove(dest, src); | |
| 109 | } | |
| 110 | ||
| 111 | comptime { | |
| 112 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 113 | const dest: []u8 = &buf; | |
| 114 | const src: [*]align(1) u16 = @ptrCast(&buf); | |
| 115 | @memmove(dest, src); | |
| 116 | } | |
| 117 | ||
| 118 | comptime { | |
| 119 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 120 | const dest: *[8]u8 = &buf; | |
| 121 | const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 122 | @memmove(dest, src); | |
| 123 | } | |
| 124 | ||
| 125 | comptime { | |
| 126 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 127 | const dest: *[8]u8 = &buf; | |
| 128 | const src: *align(1) [8]u16 = @ptrCast(&buf); | |
| 129 | @memmove(dest, src); | |
| 130 | } | |
| 131 | ||
| 132 | comptime { | |
| 133 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 134 | const dest: *[8]u8 = &buf; | |
| 135 | const src: [*]align(1) u16 = @ptrCast(&buf); | |
| 136 | @memmove(dest, src); | |
| 137 | } | |
| 138 | ||
| 139 | comptime { | |
| 140 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 141 | const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 142 | const src: []u8 = &buf; | |
| 143 | @memmove(dest, src); | |
| 144 | } | |
| 145 | ||
| 146 | comptime { | |
| 147 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 148 | const dest: *align(1) [8]u16 = @ptrCast(&buf); | |
| 149 | const src: []u8 = &buf; | |
| 150 | @memmove(dest, src); | |
| 151 | } | |
| 152 | ||
| 153 | comptime { | |
| 154 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 155 | const dest: [*]align(1) u16 = @ptrCast(&buf); | |
| 156 | const src: []u8 = &buf; | |
| 157 | @memmove(dest, src); | |
| 158 | } | |
| 159 | ||
| 160 | comptime { | |
| 161 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 162 | const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4]; | |
| 163 | const src: *[8]u8 = &buf; | |
| 164 | @memmove(dest, src); | |
| 165 | } | |
| 166 | ||
| 167 | comptime { | |
| 168 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 169 | const dest: *align(1) [8]u16 = @ptrCast(&buf); | |
| 170 | const src: *[8]u8 = &buf; | |
| 171 | @memmove(dest, src); | |
| 172 | } | |
| 173 | ||
| 174 | comptime { | |
| 175 | var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 176 | const dest: [*]align(1) u16 = @ptrCast(&buf); | |
| 177 | const src: *[8]u8 = &buf; | |
| 178 | @memmove(dest, src); | |
| 179 | } | |
| 180 | ||
| 181 | // error | |
| 182 | // | |
| 183 | // :6:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 184 | // :6:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 185 | // :14:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 186 | // :14:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 187 | // :22:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 188 | // :22:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 189 | // :30:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 190 | // :30:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 191 | // :38:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 192 | // :38:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 193 | // :46:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 194 | // :46:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 195 | // :54:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 196 | // :62:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 197 | // :70:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 198 | // :78:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 199 | // :86:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 200 | // :94:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 201 | // :101:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 202 | // :101:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 203 | // :108:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 204 | // :108:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 205 | // :115:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 206 | // :115:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 207 | // :122:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 208 | // :122:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 209 | // :129:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 210 | // :129:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 211 | // :136:5: error: pointer element type 'u16' cannot coerce into element type 'u8' | |
| 212 | // :136:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values | |
| 213 | // :143:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 214 | // :150:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 215 | // :157:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 216 | // :164:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 217 | // :171:5: error: pointer element type 'u8' cannot coerce into element type 'u16' | |
| 218 | // :178:5: error: pointer element type 'u8' cannot coerce into element type 'u16' |
test/cases/compile_errors/comptime_var_referenced_at_runtime.zig+11| ... | ... | @@ -63,6 +63,14 @@ export fn far() void { |
| 63 | 63 | @memset(&rt, elem); |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | export fn bax() void { | |
| 67 | comptime var x: [2]u32 = undefined; | |
| 68 | x = .{ 1, 2 }; | |
| 69 | ||
| 70 | var rt: [2]u32 = undefined; | |
| 71 | @memmove(&rt, &x); | |
| 72 | } | |
| 73 | ||
| 66 | 74 | // error |
| 67 | 75 | // |
| 68 | 76 | // :5:19: error: runtime value contains reference to comptime var |
| ... | ... | @@ -92,3 +100,6 @@ export fn far() void { |
| 92 | 100 | // :63:18: error: runtime value contains reference to comptime var |
| 93 | 101 | // :63:18: note: comptime var pointers are not available at runtime |
| 94 | 102 | // :59:27: note: 'runtime_value' points to comptime var declared here |
| 103 | // :71:19: error: runtime value contains reference to comptime var | |
| 104 | // :71:19: note: comptime var pointers are not available at runtime | |
| 105 | // :67:30: note: 'runtime_value' points to comptime var declared here |
test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig+43-1| ... | ... | @@ -28,10 +28,39 @@ pub export fn memcpy_const_dest_ptr() void { |
| 28 | 28 | var buf2: [5]u8 = .{ 1, 2, 3, 4, 5 }; |
| 29 | 29 | @memcpy(&buf1, &buf2); |
| 30 | 30 | } |
| 31 | pub export fn memset_array() void { | |
| 31 | pub export fn memcpy_array() void { | |
| 32 | 32 | const buf: [5]u8 = .{ 1, 2, 3, 4, 5 }; |
| 33 | 33 | @memcpy(buf, 1); |
| 34 | 34 | } |
| 35 | pub export fn entry_memmove() void { | |
| 36 | var buf: [5]u8 = .{ 1, 2, 3, 4, 5 }; | |
| 37 | const slice: []u8 = &buf; | |
| 38 | const a: u32 = 1234; | |
| 39 | @memmove(slice.ptr, @as([*]const u8, @ptrCast(&a))); | |
| 40 | } | |
| 41 | pub export fn entry1_memmove() void { | |
| 42 | var buf: [5]u8 = .{ 1, 2, 3, 4, 5 }; | |
| 43 | const ptr: *u8 = &buf[0]; | |
| 44 | @memmove(ptr, 0); | |
| 45 | } | |
| 46 | pub export fn non_matching_lengths_memmove() void { | |
| 47 | var buf1: [5]u8 = .{ 1, 2, 3, 4, 5 }; | |
| 48 | var buf2: [6]u8 = .{ 1, 2, 3, 4, 5, 6 }; | |
| 49 | @memmove(&buf2, &buf1); | |
| 50 | } | |
| 51 | pub export fn memcpy_const_dest_ptr_memmove() void { | |
| 52 | const buf1: [5]u8 = .{ 1, 2, 3, 4, 5 }; | |
| 53 | var buf2: [5]u8 = .{ 1, 2, 3, 4, 5 }; | |
| 54 | @memmove(&buf1, &buf2); | |
| 55 | } | |
| 56 | pub export fn memmove_array() void { | |
| 57 | const buf: [5]u8 = .{ 1, 2, 3, 4, 5 }; | |
| 58 | @memmove(buf, 1); | |
| 59 | } | |
| 60 | pub export fn memset_array() void { | |
| 61 | const buf: [5]u8 = .{ 1, 2, 3, 4, 5 }; | |
| 62 | @memset(buf, 1); | |
| 63 | } | |
| 35 | 64 | |
| 36 | 65 | // error |
| 37 | 66 | // backend=stage2 |
| ... | ... | @@ -51,3 +80,16 @@ pub export fn memset_array() void { |
| 51 | 80 | // :29:13: error: cannot memcpy to constant pointer |
| 52 | 81 | // :33:13: error: type '[5]u8' is not an indexable pointer |
| 53 | 82 | // :33:13: note: operand must be a slice, a many pointer or a pointer to an array |
| 83 | // :39:5: error: unknown @memmove length | |
| 84 | // :39:19: note: destination type '[*]u8' provides no length | |
| 85 | // :39:25: note: source type '[*]const u8' provides no length | |
| 86 | // :44:14: error: type '*u8' is not an indexable pointer | |
| 87 | // :44:14: note: operand must be a slice, a many pointer or a pointer to an array | |
| 88 | // :49:5: error: non-matching @memmove lengths | |
| 89 | // :49:14: note: length 6 here | |
| 90 | // :49:21: note: length 5 here | |
| 91 | // :54:14: error: cannot memmove to constant pointer | |
| 92 | // :58:14: error: type '[5]u8' is not an indexable pointer | |
| 93 | // :58:14: note: operand must be a slice, a many pointer or a pointer to an array | |
| 94 | // :62:13: error: type '[5]u8' is not an indexable pointer | |
| 95 | // :62:13: note: operand must be a slice, a many pointer or a pointer to an array |
test/cases/safety/memmove_len_mismatch.zig created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | |
| 4 | _ = stack_trace; | |
| 5 | if (std.mem.eql(u8, message, "@memmove arguments have non-equal lengths")) { | |
| 6 | std.process.exit(0); | |
| 7 | } | |
| 8 | std.process.exit(1); | |
| 9 | } | |
| 10 | pub fn main() !void { | |
| 11 | var buffer = [2]u8{ 1, 2 } ** 5; | |
| 12 | var len: usize = 5; | |
| 13 | _ = &len; | |
| 14 | @memmove(buffer[0..len], buffer[len .. len + 4]); | |
| 15 | return error.TestFailed; | |
| 16 | } | |
| 17 | // run | |
| 18 | // backend=llvm | |
| 19 | // target=native |
test/standalone/zerolength_check/src/main.zig+1| ... | ... | @@ -5,6 +5,7 @@ test { |
| 5 | 5 | const source = foo(); |
| 6 | 6 | |
| 7 | 7 | @memcpy(dest, source); |
| 8 | @memmove(dest, source); | |
| 8 | 9 | @memset(dest, 4); |
| 9 | 10 | @memset(dest, undefined); |
| 10 | 11 |