master
  1const std = @import("std");
  2const builtin = @import("builtin");
  3const expect = std.testing.expect;
  4const assert = std.debug.assert;
  5
  6test "memcpy and memset intrinsics" {
  7    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
  8    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  9    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 10
 11    try testMemcpyMemset();
 12    try comptime testMemcpyMemset();
 13}
 14
 15fn testMemcpyMemset() !void {
 16    var foo: [20]u8 = undefined;
 17    var bar: [20]u8 = undefined;
 18
 19    @memset(&foo, 'A');
 20    @memcpy(&bar, &foo);
 21
 22    try expect(bar[0] == 'A');
 23    try expect(bar[11] == 'A');
 24    try expect(bar[19] == 'A');
 25}
 26
 27test "@memcpy with both operands single-ptr-to-array, one is null-terminated" {
 28    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 29    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
 30    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 31
 32    try testMemcpyBothSinglePtrArrayOneIsNullTerminated();
 33    try comptime testMemcpyBothSinglePtrArrayOneIsNullTerminated();
 34}
 35
 36fn testMemcpyBothSinglePtrArrayOneIsNullTerminated() !void {
 37    var buf: [100]u8 = undefined;
 38    const suffix = "hello";
 39    @memcpy(buf[buf.len - suffix.len ..], suffix);
 40    try expect(buf[95] == 'h');
 41    try expect(buf[96] == 'e');
 42    try expect(buf[97] == 'l');
 43    try expect(buf[98] == 'l');
 44    try expect(buf[99] == 'o');
 45}
 46
 47test "@memcpy dest many pointer" {
 48    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 49    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
 50    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 51
 52    try testMemcpyDestManyPtr();
 53    try comptime testMemcpyDestManyPtr();
 54}
 55
 56fn testMemcpyDestManyPtr() !void {
 57    var str = "hello".*;
 58    var buf: [5]u8 = undefined;
 59    var len: usize = 5;
 60    _ = &len;
 61    @memcpy(@as([*]u8, @ptrCast(&buf)), @as([*]const u8, @ptrCast(&str))[0..len]);
 62    try expect(buf[0] == 'h');
 63    try expect(buf[1] == 'e');
 64    try expect(buf[2] == 'l');
 65    try expect(buf[3] == 'l');
 66    try expect(buf[4] == 'o');
 67}
 68
 69test "@memcpy C pointer" {
 70    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 71    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
 72    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 73
 74    try testMemcpyCPointer();
 75    try comptime testMemcpyCPointer();
 76}
 77
 78fn testMemcpyCPointer() !void {
 79    const src = "hello";
 80    var buf: [5]u8 = undefined;
 81    @memcpy(@as([*c]u8, &buf), src);
 82    try expect(buf[0] == 'h');
 83    try expect(buf[1] == 'e');
 84    try expect(buf[2] == 'l');
 85    try expect(buf[3] == 'l');
 86    try expect(buf[4] == 'o');
 87}
 88
 89test "@memcpy slice" {
 90    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 91    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 92    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
 93    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 94
 95    try testMemcpySlice();
 96    try comptime testMemcpySlice();
 97}
 98
 99fn testMemcpySlice() !void {
100    var buf: [5]u8 = undefined;
101    const dst: []u8 = &buf;
102    const src: []const u8 = "hello";
103    @memcpy(dst, src);
104    try expect(buf[0] == 'h');
105    try expect(buf[1] == 'e');
106    try expect(buf[2] == 'l');
107    try expect(buf[3] == 'l');
108    try expect(buf[4] == 'o');
109}
110
111comptime {
112    const S = struct {
113        buffer: [8]u8 = undefined,
114        fn set(self: *@This(), items: []const u8) void {
115            @memcpy(self.buffer[0..items.len], items);
116        }
117    };
118
119    var s = S{};
120    s.set("hello");
121    if (!std.mem.eql(u8, s.buffer[0..5], "hello")) @compileError("bad");
122}
123
124test "@memcpy comptime-only type" {
125    const in: [4]type = .{ u8, u16, u32, u64 };
126    comptime var out: [4]type = undefined;
127    @memcpy(&out, &in);
128
129    comptime assert(out[0] == u8);
130    comptime assert(out[1] == u16);
131    comptime assert(out[2] == u32);
132    comptime assert(out[3] == u64);
133}
134
135test "@memcpy zero-bit type with aliasing" {
136    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
137
138    const S = struct {
139        fn doTheTest() void {
140            var buf: [3]void = @splat({});
141            const slice: []void = &buf;
142            // These two pointers are the same, but it's still not considered aliasing because
143            // the input and output slices both correspond to zero bits of memory.
144            @memcpy(slice, slice);
145            comptime assert(buf[0] == {});
146            comptime assert(buf[1] == {});
147            comptime assert(buf[2] == {});
148        }
149    };
150    S.doTheTest();
151    comptime S.doTheTest();
152}
153
154test "@memcpy with sentinel" {
155    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
156    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
157
158    const S = struct {
159        fn doTheTest() void {
160            const field = @typeInfo(struct { a: u32 }).@"struct".fields[0];
161            var buffer: [field.name.len]u8 = undefined;
162            @memcpy(&buffer, field.name);
163        }
164    };
165
166    S.doTheTest();
167    comptime S.doTheTest();
168}
169
170test "@memcpy no sentinel source into sentinel destination" {
171    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
172
173    const S = struct {
174        fn doTheTest() void {
175            const src: []const u8 = &.{ 1, 2, 3 };
176            comptime var dest_buf: [3:0]u8 = @splat(0);
177            const dest: [:0]u8 = &dest_buf;
178            @memcpy(dest, src);
179        }
180    };
181
182    S.doTheTest();
183    comptime S.doTheTest();
184}