update test cases for new memcpy/memset semantics

This commit is contained in:
Andrew Kelley
2023-04-24 17:31:07 -07:00
parent 747f58366a
commit 1ba72bcf9a
11 changed files with 137 additions and 28 deletions

View File

@@ -171,10 +171,10 @@ pub inline fn __builtin_memcpy(
noalias src: ?*const anyopaque,
len: usize,
) ?*anyopaque {
const dst_cast = @ptrCast([*c]u8, dst);
const src_cast = @ptrCast([*c]const u8, src);
@memcpy(dst_cast[0..len], src_cast);
if (len > 0) @memcpy(
@ptrCast([*]u8, dst.?)[0..len],
@ptrCast([*]const u8, src.?),
);
return dst;
}

View File

@@ -20424,22 +20424,6 @@ fn checkPtrType(
return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});
}
fn checkSliceOrArrayType(
sema: *Sema,
block: *Block,
ty_src: LazySrcLoc,
ty: Type,
) CompileError!void {
if (ty.zigTypeTag() == .Pointer) {
switch (ty.ptrSize()) {
.Slice => return,
.One => if (ty.childType().zigTypeTag() == .Array) return,
else => {},
}
}
return sema.fail(block, ty_src, "expected slice or array pointer; found '{}'", .{ty.fmt(sema.mod)});
}
fn checkVectorElemType(
sema: *Sema,
block: *Block,
@@ -21993,7 +21977,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const dest_ptr = try sema.resolveInst(extra.lhs);
const uncoerced_elem = try sema.resolveInst(extra.rhs);
const dest_ptr_ty = sema.typeOf(dest_ptr);
try checkSliceOrArrayType(sema, block, dest_src, dest_ptr_ty);
try checkIndexable(sema, block, dest_src, dest_ptr_ty);
const dest_elem_ty = dest_ptr_ty.elemType2();
const target = sema.mod.getTarget();

View File

@@ -17,8 +17,8 @@ test {
try testing.expectEqual(void, @TypeOf(@breakpoint()));
try testing.expectEqual({}, @export(x, .{ .name = "x" }));
try testing.expectEqual({}, @fence(.Acquire));
try testing.expectEqual({}, @memcpy(@intToPtr([*]u8, 1), @intToPtr([*]u8, 1), 0));
try testing.expectEqual({}, @memset(@intToPtr([*]u8, 1), undefined, 0));
try testing.expectEqual({}, @memcpy(@intToPtr([*]u8, 1)[0..0], @intToPtr([*]u8, 1)[0..0]));
try testing.expectEqual({}, @memset(@intToPtr([*]u8, 1)[0..0], undefined));
try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {}));
try testing.expectEqual({}, @prefetch(&val, .{}));
try testing.expectEqual({}, @setAlignStack(16));

View File

@@ -2,18 +2,35 @@ pub export fn entry() void {
var buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
var slice: []u8 = &buf;
const a: u32 = 1234;
@memcpy(slice, @ptrCast([*]const u8, &a));
@memcpy(slice.ptr, @ptrCast([*]const u8, &a));
}
pub export fn entry1() void {
var buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
var ptr: *u8 = &buf[0];
@memcpy(ptr, 0);
}
pub export fn entry2() void {
var buf: [5]u8 = .{ 1, 2, 3, 4, 5 };
var ptr: *u8 = &buf[0];
@memset(ptr, 0);
}
pub export fn non_matching_lengths() void {
var buf1: [5]u8 = .{ 1, 2, 3, 4, 5 };
var buf2: [6]u8 = .{ 1, 2, 3, 4, 5, 6 };
@memcpy(&buf2, &buf1);
}
// error
// backend=stage2
// target=native
//
// :5:13: error: expected type '[*]u8', found '[]u8'
// :10:13: error: expected type '[*]u8', found '*u8'
// :10:13: note: a single pointer cannot cast into a many pointer
// :5:5: error: unknown @memcpy length
// :5:18: note: destination type [*]u8 provides no length
// :5:24: note: source type [*]align(4) const u8 provides no length
// :10:13: error: type 'u8' does not support indexing
// :10:13: note: for loop operand must be an array, slice, tuple, or vector
// :15:13: error: type '*u8' does not support indexing
// :15:13: note: for loop operand must be an array, slice, tuple, or vector
// :20:5: error: non-matching @memcpy lengths
// :20:13: note: length 6 here
// :20:20: note: length 5 here

View File

@@ -0,0 +1,17 @@
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, "@memcpy arguments alias")) {
std.process.exit(0);
}
std.process.exit(1);
}
pub fn main() !void {
var buffer = [2]u8{ 1, 2 } ** 5;
var len: usize = 5;
@memcpy(buffer[0..len], buffer[4 .. 4 + len]);
}
// run
// backend=llvm
// target=native

View File

@@ -0,0 +1,17 @@
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, "@memcpy 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;
@memcpy(buffer[0..len], buffer[len .. len + 4]);
}
// run
// backend=llvm
// target=native

View File

@@ -0,0 +1,18 @@
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, "integer overflow")) {
std.process.exit(0);
}
std.process.exit(1);
}
pub fn main() !void {
var buffer = [6]u8{ 1, 2, 3, 4, 5, 6 };
@memset(&buffer, undefined);
var x: u8 = buffer[1];
x += buffer[2];
}
// run
// backend=llvm
// target=native

View File

@@ -0,0 +1,18 @@
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, "integer overflow")) {
std.process.exit(0);
}
std.process.exit(1);
}
pub fn main() !void {
var buffer = [6]i32{ 1, 2, 3, 4, 5, 6 };
@memset(&buffer, undefined);
var x: i32 = buffer[1];
x += buffer[2];
}
// run
// backend=llvm
// target=native

View 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, "integer overflow")) {
std.process.exit(0);
}
std.process.exit(1);
}
pub fn main() !void {
var buffer = [6]u8{ 1, 2, 3, 4, 5, 6 };
var len = buffer.len;
@memset(buffer[0..len], undefined);
var x: u8 = buffer[1];
x += buffer[2];
}
// run
// backend=llvm
// target=native

View 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, "integer overflow")) {
std.process.exit(0);
}
std.process.exit(1);
}
pub fn main() !void {
var buffer = [6]i32{ 1, 2, 3, 4, 5, 6 };
var len = buffer.len;
@memset(buffer[0..len], undefined);
var x: i32 = buffer[1];
x += buffer[2];
}
// run
// backend=llvm
// target=native

View File

@@ -15,7 +15,7 @@ const U = union(enum(u32)) {
pub fn main() !void {
var u: U = undefined;
@memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
@memset(@ptrCast([*]u8, &u)[0..@sizeOf(U)], 0x55);
switch (u) {
.X, .Y => @breakpoint(),
}