mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
test: add tests for @memmove
This commit is contained in:
parent
898ca82458
commit
4e78836d29
8 changed files with 478 additions and 1 deletions
|
|
@ -55,6 +55,7 @@ test {
|
||||||
_ = @import("behavior/member_func.zig");
|
_ = @import("behavior/member_func.zig");
|
||||||
_ = @import("behavior/memcpy.zig");
|
_ = @import("behavior/memcpy.zig");
|
||||||
_ = @import("behavior/memset.zig");
|
_ = @import("behavior/memset.zig");
|
||||||
|
_ = @import("behavior/memmove.zig");
|
||||||
_ = @import("behavior/merge_error_sets.zig");
|
_ = @import("behavior/merge_error_sets.zig");
|
||||||
_ = @import("behavior/muladd.zig");
|
_ = @import("behavior/muladd.zig");
|
||||||
_ = @import("behavior/multiple_externs_with_conflicting_types.zig");
|
_ = @import("behavior/multiple_externs_with_conflicting_types.zig");
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ var x: u8 = 1;
|
||||||
|
|
||||||
// This excludes builtin functions that return void or noreturn that cannot be tested.
|
// This excludes builtin functions that return void or noreturn that cannot be tested.
|
||||||
test {
|
test {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
|
|
@ -17,6 +18,7 @@ test {
|
||||||
try testing.expectEqual(void, @TypeOf(@breakpoint()));
|
try testing.expectEqual(void, @TypeOf(@breakpoint()));
|
||||||
try testing.expectEqual({}, @export(&x, .{ .name = "x" }));
|
try testing.expectEqual({}, @export(&x, .{ .name = "x" }));
|
||||||
try testing.expectEqual({}, @memcpy(@as([*]u8, @ptrFromInt(1))[0..0], @as([*]u8, @ptrFromInt(1))[0..0]));
|
try testing.expectEqual({}, @memcpy(@as([*]u8, @ptrFromInt(1))[0..0], @as([*]u8, @ptrFromInt(1))[0..0]));
|
||||||
|
try testing.expectEqual({}, @memmove(@as([*]u8, @ptrFromInt(1))[0..0], @as([*]u8, @ptrFromInt(1))[0..0]));
|
||||||
try testing.expectEqual({}, @memset(@as([*]u8, @ptrFromInt(1))[0..0], undefined));
|
try testing.expectEqual({}, @memset(@as([*]u8, @ptrFromInt(1))[0..0], undefined));
|
||||||
try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {}));
|
try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {}));
|
||||||
try testing.expectEqual({}, @prefetch(&val, .{}));
|
try testing.expectEqual({}, @prefetch(&val, .{}));
|
||||||
|
|
|
||||||
183
test/behavior/memmove.zig
Normal file
183
test/behavior/memmove.zig
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
|
||||||
|
test "memmove and memset intrinsics" {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
|
try testMemmoveMemset();
|
||||||
|
try comptime testMemmoveMemset();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testMemmoveMemset() !void {
|
||||||
|
var foo: [20]u8 = undefined;
|
||||||
|
|
||||||
|
@memset(foo[0..10], 'A');
|
||||||
|
@memset(foo[10..20], 'B');
|
||||||
|
|
||||||
|
try expect(foo[0] == 'A');
|
||||||
|
try expect(foo[11] == 'B');
|
||||||
|
try expect(foo[19] == 'B');
|
||||||
|
|
||||||
|
@memmove(foo[10..20], foo[0..10]);
|
||||||
|
|
||||||
|
try expect(foo[0] == 'A');
|
||||||
|
try expect(foo[11] == 'A');
|
||||||
|
try expect(foo[19] == 'A');
|
||||||
|
}
|
||||||
|
|
||||||
|
test "@memmove with both operands single-ptr-to-array, one is null-terminated" {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
|
try testMemmoveBothSinglePtrArrayOneIsNullTerminated();
|
||||||
|
try comptime testMemmoveBothSinglePtrArrayOneIsNullTerminated();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testMemmoveBothSinglePtrArrayOneIsNullTerminated() !void {
|
||||||
|
var buf: [100]u8 = undefined;
|
||||||
|
const suffix = "hello";
|
||||||
|
@memmove(buf[buf.len - suffix.len ..], suffix);
|
||||||
|
try expect(buf[95] == 'h');
|
||||||
|
try expect(buf[96] == 'e');
|
||||||
|
try expect(buf[97] == 'l');
|
||||||
|
try expect(buf[98] == 'l');
|
||||||
|
try expect(buf[99] == 'o');
|
||||||
|
|
||||||
|
const start = buf.len - suffix.len - 3;
|
||||||
|
const end = start + suffix.len;
|
||||||
|
@memmove(buf[start..end], buf[buf.len - suffix.len ..]);
|
||||||
|
try expect(buf[92] == 'h');
|
||||||
|
try expect(buf[93] == 'e');
|
||||||
|
try expect(buf[94] == 'l');
|
||||||
|
try expect(buf[95] == 'l');
|
||||||
|
try expect(buf[96] == 'o');
|
||||||
|
try expect(buf[97] == 'l');
|
||||||
|
try expect(buf[98] == 'l');
|
||||||
|
try expect(buf[99] == 'o');
|
||||||
|
|
||||||
|
@memmove(buf[start + 2 .. end + 2], buf[start..end]);
|
||||||
|
try expect(buf[92] == 'h');
|
||||||
|
try expect(buf[93] == 'e');
|
||||||
|
try expect(buf[94] == 'h');
|
||||||
|
try expect(buf[95] == 'e');
|
||||||
|
try expect(buf[96] == 'l');
|
||||||
|
try expect(buf[97] == 'l');
|
||||||
|
try expect(buf[98] == 'o');
|
||||||
|
try expect(buf[99] == 'o');
|
||||||
|
}
|
||||||
|
|
||||||
|
test "@memmove dest many pointer" {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
|
try testMemmoveDestManyPtr();
|
||||||
|
try comptime testMemmoveDestManyPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testMemmoveDestManyPtr() !void {
|
||||||
|
var str = "hello".*;
|
||||||
|
var buf: [8]u8 = undefined;
|
||||||
|
var len: usize = 5;
|
||||||
|
_ = &len;
|
||||||
|
@memmove(@as([*]u8, @ptrCast(&buf)), @as([*]const u8, @ptrCast(&str))[0..len]);
|
||||||
|
try expect(buf[0] == 'h');
|
||||||
|
try expect(buf[1] == 'e');
|
||||||
|
try expect(buf[2] == 'l');
|
||||||
|
try expect(buf[3] == 'l');
|
||||||
|
try expect(buf[4] == 'o');
|
||||||
|
@memmove(buf[3..].ptr, buf[0..len]);
|
||||||
|
try expect(buf[0] == 'h');
|
||||||
|
try expect(buf[1] == 'e');
|
||||||
|
try expect(buf[2] == 'l');
|
||||||
|
try expect(buf[3] == 'h');
|
||||||
|
try expect(buf[4] == 'e');
|
||||||
|
try expect(buf[5] == 'l');
|
||||||
|
try expect(buf[6] == 'l');
|
||||||
|
try expect(buf[7] == 'o');
|
||||||
|
@memmove(buf[2..7].ptr, buf[3 .. len + 3]);
|
||||||
|
try expect(buf[0] == 'h');
|
||||||
|
try expect(buf[1] == 'e');
|
||||||
|
try expect(buf[2] == 'h');
|
||||||
|
try expect(buf[3] == 'e');
|
||||||
|
try expect(buf[4] == 'l');
|
||||||
|
try expect(buf[5] == 'l');
|
||||||
|
try expect(buf[6] == 'o');
|
||||||
|
try expect(buf[7] == 'o');
|
||||||
|
}
|
||||||
|
|
||||||
|
test "@memmove slice" {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
||||||
|
|
||||||
|
try testMemmoveSlice();
|
||||||
|
try comptime testMemmoveSlice();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testMemmoveSlice() !void {
|
||||||
|
var buf: [8]u8 = undefined;
|
||||||
|
const dst1: []u8 = buf[0..5];
|
||||||
|
const dst2: []u8 = buf[3..8];
|
||||||
|
const dst3: []u8 = buf[2..7];
|
||||||
|
const src: []const u8 = "hello";
|
||||||
|
@memmove(dst1, src);
|
||||||
|
try expect(buf[0] == 'h');
|
||||||
|
try expect(buf[1] == 'e');
|
||||||
|
try expect(buf[2] == 'l');
|
||||||
|
try expect(buf[3] == 'l');
|
||||||
|
try expect(buf[4] == 'o');
|
||||||
|
@memmove(dst2, dst1);
|
||||||
|
try expect(buf[0] == 'h');
|
||||||
|
try expect(buf[1] == 'e');
|
||||||
|
try expect(buf[2] == 'l');
|
||||||
|
try expect(buf[3] == 'h');
|
||||||
|
try expect(buf[4] == 'e');
|
||||||
|
try expect(buf[5] == 'l');
|
||||||
|
try expect(buf[6] == 'l');
|
||||||
|
try expect(buf[7] == 'o');
|
||||||
|
@memmove(dst3, dst2);
|
||||||
|
try expect(buf[0] == 'h');
|
||||||
|
try expect(buf[1] == 'e');
|
||||||
|
try expect(buf[2] == 'h');
|
||||||
|
try expect(buf[3] == 'e');
|
||||||
|
try expect(buf[4] == 'l');
|
||||||
|
try expect(buf[5] == 'l');
|
||||||
|
try expect(buf[6] == 'o');
|
||||||
|
try expect(buf[7] == 'o');
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
const S = struct {
|
||||||
|
buffer: [8]u8 = undefined,
|
||||||
|
fn set(self: *@This(), items: []const u8) void {
|
||||||
|
@memmove(self.buffer[0..items.len], items);
|
||||||
|
@memmove(self.buffer[3..], self.buffer[0..items.len]);
|
||||||
|
@memmove(self.buffer[2 .. 2 + items.len], self.buffer[3..]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s = S{};
|
||||||
|
s.set("hello");
|
||||||
|
if (!std.mem.eql(u8, s.buffer[0..8], "hehelloo")) @compileError("bad");
|
||||||
|
}
|
||||||
218
test/cases/compile_errors/@memmove_type_mismatch.zig
Normal file
218
test/cases/compile_errors/@memmove_type_mismatch.zig
Normal file
|
|
@ -0,0 +1,218 @@
|
||||||
|
export fn foo() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []u8 = &buf;
|
||||||
|
const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn bar() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []u8 = &buf;
|
||||||
|
const src: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn baz() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []u8 = &buf;
|
||||||
|
const src: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn qux() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *[8]u8 = &buf;
|
||||||
|
const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn quux() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *[8]u8 = &buf;
|
||||||
|
const src: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn quuux() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *[8]u8 = &buf;
|
||||||
|
const src: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn foo2() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
const src: []u8 = &buf;
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn bar2() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
const src: []u8 = &buf;
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn baz2() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
const src: []u8 = &buf;
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn qux2() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
const src: *[8]u8 = &buf;
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn quux2() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
const src: *[8]u8 = &buf;
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn quuux2() void {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
const src: *[8]u8 = &buf;
|
||||||
|
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []u8 = &buf;
|
||||||
|
const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []u8 = &buf;
|
||||||
|
const src: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []u8 = &buf;
|
||||||
|
const src: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *[8]u8 = &buf;
|
||||||
|
const src: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *[8]u8 = &buf;
|
||||||
|
const src: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *[8]u8 = &buf;
|
||||||
|
const src: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
const src: []u8 = &buf;
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
const src: []u8 = &buf;
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
const src: []u8 = &buf;
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: []align(1) u16 = @as([*]align(1) u16, @ptrCast(&buf))[0..4];
|
||||||
|
const src: *[8]u8 = &buf;
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: *align(1) [8]u16 = @ptrCast(&buf);
|
||||||
|
const src: *[8]u8 = &buf;
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
var buf: [8]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
const dest: [*]align(1) u16 = @ptrCast(&buf);
|
||||||
|
const src: *[8]u8 = &buf;
|
||||||
|
@memmove(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
//
|
||||||
|
// :6:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :6:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :14:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :14:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :22:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :22:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :30:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :30:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :38:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :38:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :46:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :46:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :54:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :62:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :70:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :78:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :86:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :94:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :101:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :101:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :108:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :108:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :115:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :115:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :122:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :122:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :129:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :129:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :136:5: error: pointer element type 'u16' cannot coerce into element type 'u8'
|
||||||
|
// :136:5: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values
|
||||||
|
// :143:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :150:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :157:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :164:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :171:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
// :178:5: error: pointer element type 'u8' cannot coerce into element type 'u16'
|
||||||
|
|
@ -63,6 +63,14 @@ export fn far() void {
|
||||||
@memset(&rt, elem);
|
@memset(&rt, elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export fn bax() void {
|
||||||
|
comptime var x: [2]u32 = undefined;
|
||||||
|
x = .{ 1, 2 };
|
||||||
|
|
||||||
|
var rt: [2]u32 = undefined;
|
||||||
|
@memmove(&rt, &x);
|
||||||
|
}
|
||||||
|
|
||||||
// error
|
// error
|
||||||
//
|
//
|
||||||
// :5:19: error: runtime value contains reference to comptime var
|
// :5:19: error: runtime value contains reference to comptime var
|
||||||
|
|
@ -92,3 +100,6 @@ export fn far() void {
|
||||||
// :63:18: error: runtime value contains reference to comptime var
|
// :63:18: error: runtime value contains reference to comptime var
|
||||||
// :63:18: note: comptime var pointers are not available at runtime
|
// :63:18: note: comptime var pointers are not available at runtime
|
||||||
// :59:27: note: 'runtime_value' points to comptime var declared here
|
// :59:27: note: 'runtime_value' points to comptime var declared here
|
||||||
|
// :71:19: error: runtime value contains reference to comptime var
|
||||||
|
// :71:19: note: comptime var pointers are not available at runtime
|
||||||
|
// :67:30: note: 'runtime_value' points to comptime var declared here
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,39 @@ pub export fn memcpy_const_dest_ptr() void {
|
||||||
var buf2: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
var buf2: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
@memcpy(&buf1, &buf2);
|
@memcpy(&buf1, &buf2);
|
||||||
}
|
}
|
||||||
pub export fn memset_array() void {
|
pub export fn memcpy_array() void {
|
||||||
const buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
const buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
@memcpy(buf, 1);
|
@memcpy(buf, 1);
|
||||||
}
|
}
|
||||||
|
pub export fn entry_memmove() void {
|
||||||
|
var buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
|
const slice: []u8 = &buf;
|
||||||
|
const a: u32 = 1234;
|
||||||
|
@memmove(slice.ptr, @as([*]const u8, @ptrCast(&a)));
|
||||||
|
}
|
||||||
|
pub export fn entry1_memmove() void {
|
||||||
|
var buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
|
const ptr: *u8 = &buf[0];
|
||||||
|
@memmove(ptr, 0);
|
||||||
|
}
|
||||||
|
pub export fn non_matching_lengths_memmove() void {
|
||||||
|
var buf1: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
|
var buf2: [6]u8 = .{ 1, 2, 3, 4, 5, 6 };
|
||||||
|
@memmove(&buf2, &buf1);
|
||||||
|
}
|
||||||
|
pub export fn memcpy_const_dest_ptr_memmove() void {
|
||||||
|
const buf1: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
|
var buf2: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
|
@memmove(&buf1, &buf2);
|
||||||
|
}
|
||||||
|
pub export fn memmove_array() void {
|
||||||
|
const buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
|
@memmove(buf, 1);
|
||||||
|
}
|
||||||
|
pub export fn memset_array() void {
|
||||||
|
const buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
|
||||||
|
@memset(buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
// error
|
// error
|
||||||
// backend=stage2
|
// backend=stage2
|
||||||
|
|
@ -51,3 +80,16 @@ pub export fn memset_array() void {
|
||||||
// :29:13: error: cannot memcpy to constant pointer
|
// :29:13: error: cannot memcpy to constant pointer
|
||||||
// :33:13: error: type '[5]u8' is not an indexable pointer
|
// :33:13: error: type '[5]u8' is not an indexable pointer
|
||||||
// :33:13: note: operand must be a slice, a many pointer or a pointer to an array
|
// :33:13: note: operand must be a slice, a many pointer or a pointer to an array
|
||||||
|
// :39:5: error: unknown @memmove length
|
||||||
|
// :39:19: note: destination type '[*]u8' provides no length
|
||||||
|
// :39:25: note: source type '[*]const u8' provides no length
|
||||||
|
// :44:14: error: type '*u8' is not an indexable pointer
|
||||||
|
// :44:14: note: operand must be a slice, a many pointer or a pointer to an array
|
||||||
|
// :49:5: error: non-matching @memmove lengths
|
||||||
|
// :49:14: note: length 6 here
|
||||||
|
// :49:21: note: length 5 here
|
||||||
|
// :54:14: error: cannot memmove to constant pointer
|
||||||
|
// :58:14: error: type '[5]u8' is not an indexable pointer
|
||||||
|
// :58:14: note: operand must be a slice, a many pointer or a pointer to an array
|
||||||
|
// :62:13: error: type '[5]u8' is not an indexable pointer
|
||||||
|
// :62:13: note: operand must be a slice, a many pointer or a pointer to an array
|
||||||
|
|
|
||||||
19
test/cases/safety/memmove_len_mismatch.zig
Normal file
19
test/cases/safety/memmove_len_mismatch.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||||
|
_ = stack_trace;
|
||||||
|
if (std.mem.eql(u8, message, "@memmove arguments have non-equal lengths")) {
|
||||||
|
std.process.exit(0);
|
||||||
|
}
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
pub fn main() !void {
|
||||||
|
var buffer = [2]u8{ 1, 2 } ** 5;
|
||||||
|
var len: usize = 5;
|
||||||
|
_ = &len;
|
||||||
|
@memmove(buffer[0..len], buffer[len .. len + 4]);
|
||||||
|
return error.TestFailed;
|
||||||
|
}
|
||||||
|
// run
|
||||||
|
// backend=llvm
|
||||||
|
// target=native
|
||||||
|
|
@ -5,6 +5,7 @@ test {
|
||||||
const source = foo();
|
const source = foo();
|
||||||
|
|
||||||
@memcpy(dest, source);
|
@memcpy(dest, source);
|
||||||
|
@memmove(dest, source);
|
||||||
@memset(dest, 4);
|
@memset(dest, 4);
|
||||||
@memset(dest, undefined);
|
@memset(dest, undefined);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue