commit 7e68999f79228a693fb1d42d6281b7d7f3e2a9de (tree)
parent 470dac8a77806c1e4faf00091076230f50c9fb8d
Author: xdBronch <51252236+xdBronch@users.noreply.github.com>
Date: Sun, 9 Mar 2025 23:03:06 -0400
Sema: fix memcpy with C pointers
Diffstat:
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -3669,7 +3669,10 @@ fn indexablePtrLenOrNone(
const zcu = pt.zcu;
const operand_ty = sema.typeOf(operand);
try checkMemOperand(sema, block, src, operand_ty);
- if (operand_ty.ptrSize(zcu) == .many) return .none;
+ switch (operand_ty.ptrSize(zcu)) {
+ .many, .c => return .none,
+ .one, .slice => {},
+ }
const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
return sema.fieldVal(block, src, operand, field_name, src);
}
diff --git a/test/behavior/memcpy.zig b/test/behavior/memcpy.zig
@@ -69,6 +69,27 @@ fn testMemcpyDestManyPtr() !void {
try expect(buf[4] == 'o');
}
+test "@memcpy C pointer" {
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
+
+ try testMemcpyCPointer();
+ try comptime testMemcpyCPointer();
+}
+
+fn testMemcpyCPointer() !void {
+ const src = "hello";
+ var buf: [5]u8 = undefined;
+ @memcpy(@as([*c]u8, &buf), src);
+ try expect(buf[0] == 'h');
+ try expect(buf[1] == 'e');
+ try expect(buf[2] == 'l');
+ try expect(buf[3] == 'l');
+ try expect(buf[4] == 'o');
+}
+
test "@memcpy slice" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;