aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-04-27 14:39:21 -0400
committerGitHub <noreply@github.com>2025-04-27 14:39:21 -0400
commit1b76d4c53adafebcbfcf0476276375353139dacb (patch)
tree5854ca686d0d016e2d109766fa17742fff27c6ac /lib/std
parent227d2b15e449db1e84788d2c87e4f49100d316ca (diff)
parent2e9c1553ef40e9f21c2241294b8942369ef9007a (diff)
downloadzig-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.zig4
-rw-r--r--lib/std/debug/no_panic.zig5
-rw-r--r--lib/std/debug/simple_panic.zig4
-rw-r--r--lib/std/mem.zig2
-rw-r--r--lib/std/zig/AstGen.zig8
-rw-r--r--lib/std/zig/AstRlAnnotate.zig2
-rw-r--r--lib/std/zig/BuiltinFn.zig8
-rw-r--r--lib/std/zig/Zir.zig7
-rw-r--r--lib/std/zig/llvm/Builder.zig30
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,