diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-04-24 17:31:07 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-04-25 11:23:41 -0700 |
| commit | 1ba72bcf9a86060fc39117f89536a971ace620c4 (patch) | |
| tree | 0c4b819a94bdc1692a17d4a0e542505d1f9c0b6e | |
| parent | 747f58366a25593431a0e8ff85d76095e0e39e74 (diff) | |
| download | zig-1ba72bcf9a86060fc39117f89536a971ace620c4.tar.gz zig-1ba72bcf9a86060fc39117f89536a971ace620c4.zip | |
update test cases for new memcpy/memset semantics
| -rw-r--r-- | lib/std/zig/c_builtins.zig | 8 | ||||
| -rw-r--r-- | src/Sema.zig | 18 | ||||
| -rw-r--r-- | test/behavior/builtin_functions_returning_void_or_noreturn.zig | 4 | ||||
| -rw-r--r-- | test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig | 25 | ||||
| -rw-r--r-- | test/cases/safety/memcpy_alias.zig | 17 | ||||
| -rw-r--r-- | test/cases/safety/memcpy_len_mismatch.zig | 17 | ||||
| -rw-r--r-- | test/cases/safety/memset_array_undefined_bytes.zig | 18 | ||||
| -rw-r--r-- | test/cases/safety/memset_array_undefined_large.zig | 18 | ||||
| -rw-r--r-- | test/cases/safety/memset_slice_undefined_bytes.zig | 19 | ||||
| -rw-r--r-- | test/cases/safety/memset_slice_undefined_large.zig | 19 | ||||
| -rw-r--r-- | test/cases/safety/switch on corrupted union value.zig | 2 |
11 files changed, 137 insertions, 28 deletions
diff --git a/lib/std/zig/c_builtins.zig b/lib/std/zig/c_builtins.zig index ea6559d457..b28134c7cd 100644 --- a/lib/std/zig/c_builtins.zig +++ b/lib/std/zig/c_builtins.zig @@ -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; } diff --git a/src/Sema.zig b/src/Sema.zig index 69b09f63ea..a2d667fd78 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -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(); diff --git a/test/behavior/builtin_functions_returning_void_or_noreturn.zig b/test/behavior/builtin_functions_returning_void_or_noreturn.zig index 0d4598bd09..d32215c964 100644 --- a/test/behavior/builtin_functions_returning_void_or_noreturn.zig +++ b/test/behavior/builtin_functions_returning_void_or_noreturn.zig @@ -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)); diff --git a/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig b/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig index 37d0b8d323..910ec807a8 100644 --- a/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig +++ b/test/cases/compile_errors/incorrect_type_to_memset_memcpy.zig @@ -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 diff --git a/test/cases/safety/memcpy_alias.zig b/test/cases/safety/memcpy_alias.zig new file mode 100644 index 0000000000..cf2da08f0c --- /dev/null +++ b/test/cases/safety/memcpy_alias.zig @@ -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 diff --git a/test/cases/safety/memcpy_len_mismatch.zig b/test/cases/safety/memcpy_len_mismatch.zig new file mode 100644 index 0000000000..b5cb887c31 --- /dev/null +++ b/test/cases/safety/memcpy_len_mismatch.zig @@ -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 diff --git a/test/cases/safety/memset_array_undefined_bytes.zig b/test/cases/safety/memset_array_undefined_bytes.zig new file mode 100644 index 0000000000..e0ce2dac04 --- /dev/null +++ b/test/cases/safety/memset_array_undefined_bytes.zig @@ -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 diff --git a/test/cases/safety/memset_array_undefined_large.zig b/test/cases/safety/memset_array_undefined_large.zig new file mode 100644 index 0000000000..dbc1cf4420 --- /dev/null +++ b/test/cases/safety/memset_array_undefined_large.zig @@ -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 diff --git a/test/cases/safety/memset_slice_undefined_bytes.zig b/test/cases/safety/memset_slice_undefined_bytes.zig new file mode 100644 index 0000000000..70acc5fa65 --- /dev/null +++ b/test/cases/safety/memset_slice_undefined_bytes.zig @@ -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 diff --git a/test/cases/safety/memset_slice_undefined_large.zig b/test/cases/safety/memset_slice_undefined_large.zig new file mode 100644 index 0000000000..66298993c0 --- /dev/null +++ b/test/cases/safety/memset_slice_undefined_large.zig @@ -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 diff --git a/test/cases/safety/switch on corrupted union value.zig b/test/cases/safety/switch on corrupted union value.zig index bfb755514a..745a3fd037 100644 --- a/test/cases/safety/switch on corrupted union value.zig +++ b/test/cases/safety/switch on corrupted union value.zig @@ -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(), } |
