diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-04-27 14:39:21 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-27 14:39:21 -0400 |
| commit | 1b76d4c53adafebcbfcf0476276375353139dacb (patch) | |
| tree | 5854ca686d0d016e2d109766fa17742fff27c6ac /lib/std | |
| parent | 227d2b15e449db1e84788d2c87e4f49100d316ca (diff) | |
| parent | 2e9c1553ef40e9f21c2241294b8942369ef9007a (diff) | |
| download | zig-1b76d4c53adafebcbfcf0476276375353139dacb.tar.gz zig-1b76d4c53adafebcbfcf0476276375353139dacb.zip | |
Merge pull request #22605 from dweiller/memmove
add `@memmove` builtin
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/debug.zig | 4 | ||||
| -rw-r--r-- | lib/std/debug/no_panic.zig | 5 | ||||
| -rw-r--r-- | lib/std/debug/simple_panic.zig | 4 | ||||
| -rw-r--r-- | lib/std/mem.zig | 2 | ||||
| -rw-r--r-- | lib/std/zig/AstGen.zig | 8 | ||||
| -rw-r--r-- | lib/std/zig/AstRlAnnotate.zig | 2 | ||||
| -rw-r--r-- | lib/std/zig/BuiltinFn.zig | 8 | ||||
| -rw-r--r-- | lib/std/zig/Zir.zig | 7 | ||||
| -rw-r--r-- | lib/std/zig/llvm/Builder.zig | 30 |
9 files changed, 69 insertions, 1 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 664999caa0..722bcc74a9 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -134,6 +134,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { @branchHint(.cold); call("@memcpy arguments alias", @returnAddress()); } + pub fn memmoveLenMismatch() noreturn { + @branchHint(.cold); + call("@memmove arguments have non-equal lengths", @returnAddress()); + } pub fn noreturnReturned() noreturn { @branchHint(.cold); call("'noreturn' function returned", @returnAddress()); diff --git a/lib/std/debug/no_panic.zig b/lib/std/debug/no_panic.zig index 934751b937..ccecc89a87 100644 --- a/lib/std/debug/no_panic.zig +++ b/lib/std/debug/no_panic.zig @@ -135,6 +135,11 @@ pub fn memcpyAlias() noreturn { @trap(); } +pub fn memmoveLenMismatch() noreturn { + @branchHint(.cold); + @trap(); +} + pub fn noreturnReturned() noreturn { @branchHint(.cold); @trap(); diff --git a/lib/std/debug/simple_panic.zig b/lib/std/debug/simple_panic.zig index 21016f395a..724061021f 100644 --- a/lib/std/debug/simple_panic.zig +++ b/lib/std/debug/simple_panic.zig @@ -128,6 +128,10 @@ pub fn memcpyAlias() noreturn { call("@memcpy arguments alias", null); } +pub fn memmoveLenMismatch() noreturn { + call("@memmove arguments have non-equal lengths", null); +} + pub fn noreturnReturned() noreturn { call("'noreturn' function returned", null); } diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 4c198408b5..a6c4fe90be 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -232,6 +232,7 @@ test "Allocator alloc and remap with zero-bit type" { /// Copy all of source into dest at position 0. /// dest.len must be >= source.len. /// If the slices overlap, dest.ptr must be <= src.ptr. +/// This function is deprecated; use @memmove instead. pub fn copyForwards(comptime T: type, dest: []T, source: []const T) void { for (dest[0..source.len], source) |*d, s| d.* = s; } @@ -239,6 +240,7 @@ pub fn copyForwards(comptime T: type, dest: []T, source: []const T) void { /// Copy all of source into dest at position 0. /// dest.len must be >= source.len. /// If the slices overlap, dest.ptr must be >= src.ptr. +/// This function is deprecated; use @memmove instead. pub fn copyBackwards(comptime T: type, dest: []T, source: []const T) void { // TODO instead of manually doing this check for the whole array // and turning off runtime safety, the compiler should detect loops like diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index 74fbd03adb..55bc743951 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -2919,6 +2919,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .set_runtime_safety, .memcpy, .memset, + .memmove, .validate_deref, .validate_destructure, .save_err_ret_index, @@ -9717,6 +9718,13 @@ fn builtinCall( }); return rvalue(gz, ri, .void_value, node); }, + .memmove => { + _ = try gz.addPlNode(.memmove, node, Zir.Inst.Bin{ + .lhs = try expr(gz, scope, .{ .rl = .none }, params[0]), + .rhs = try expr(gz, scope, .{ .rl = .none }, params[1]), + }); + return rvalue(gz, ri, .void_value, node); + }, .shuffle => { const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{ .elem_type = try typeExpr(gz, scope, params[0]), diff --git a/lib/std/zig/AstRlAnnotate.zig b/lib/std/zig/AstRlAnnotate.zig index d5fb0a8169..628574349b 100644 --- a/lib/std/zig/AstRlAnnotate.zig +++ b/lib/std/zig/AstRlAnnotate.zig @@ -1055,7 +1055,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. _ = try astrl.expr(args[2], block, ResultInfo.none); return false; }, - .memcpy => { + .memcpy, .memmove => { _ = try astrl.expr(args[0], block, ResultInfo.none); _ = try astrl.expr(args[1], block, ResultInfo.none); return false; diff --git a/lib/std/zig/BuiltinFn.zig b/lib/std/zig/BuiltinFn.zig index 1bf31cd165..818362a371 100644 --- a/lib/std/zig/BuiltinFn.zig +++ b/lib/std/zig/BuiltinFn.zig @@ -68,6 +68,7 @@ pub const Tag = enum { max, memcpy, memset, + memmove, min, wasm_memory_size, wasm_memory_grow, @@ -642,6 +643,13 @@ pub const list = list: { }, }, .{ + "@memmove", + .{ + .tag = .memmove, + .param_count = 2, + }, + }, + .{ "@min", .{ .tag = .min, diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig index 089bc5e2ae..d40322f51f 100644 --- a/lib/std/zig/Zir.zig +++ b/lib/std/zig/Zir.zig @@ -986,6 +986,9 @@ pub const Inst = struct { /// Implements the `@memset` builtin. /// Uses the `pl_node` union field with payload `Bin`. memset, + /// Implements the `@memmove` builtin. + /// Uses the `pl_node` union field with payload `Bin`. + memmove, /// Implements the `@min` builtin for 2 args. /// Uses the `pl_node` union field with payload `Bin` min, @@ -1272,6 +1275,7 @@ pub const Inst = struct { .max, .memcpy, .memset, + .memmove, .min, .c_import, .@"resume", @@ -1355,6 +1359,7 @@ pub const Inst = struct { .set_runtime_safety, .memcpy, .memset, + .memmove, .check_comptime_control_flow, .@"defer", .defer_err_code, @@ -1832,6 +1837,7 @@ pub const Inst = struct { .max = .pl_node, .memcpy = .pl_node, .memset = .pl_node, + .memmove = .pl_node, .min = .pl_node, .c_import = .pl_node, @@ -4291,6 +4297,7 @@ fn findTrackableInner( .mul_add, .memcpy, .memset, + .memmove, .min, .max, .alloc, diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index a713830161..d8d5ff19c7 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -6125,6 +6125,36 @@ pub const WipFunction = struct { return value.unwrap().instruction; } + pub fn callMemMove( + self: *WipFunction, + dst: Value, + dst_align: Alignment, + src: Value, + src_align: Alignment, + len: Value, + kind: MemoryAccessKind, + ) Allocator.Error!Instruction.Index { + var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })}; + var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = src_align })}; + const value = try self.callIntrinsic( + .normal, + try self.builder.fnAttrs(&.{ + .none, + .none, + try self.builder.attrs(&dst_attrs), + try self.builder.attrs(&src_attrs), + }), + .memmove, + &.{ dst.typeOfWip(self), src.typeOfWip(self), len.typeOfWip(self) }, + &.{ dst, src, len, switch (kind) { + .normal => Value.false, + .@"volatile" => Value.true, + } }, + undefined, + ); + return value.unwrap().instruction; + } + pub fn callMemSet( self: *WipFunction, dst: Value, |
