authorgravatar for 51252236+xdBronch@users.noreply.github.comxdBronch <51252236+xdBronch@users.noreply.github.com> 2025-03-09 23:03:06-04:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-04-28 12:10:04+02:00
log7e68999f79228a693fb1d42d6281b7d7f3e2a9de
tree5421c7939bbaf46102626e0ba47057bae2f6b908
parent470dac8a77806c1e4faf00091076230f50c9fb8d
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Sema: fix memcpy with C pointers


2 files changed, 25 insertions(+), 1 deletions(-)

src/Sema.zig+4-1
...@@ -3669,7 +3669,10 @@ fn indexablePtrLenOrNone(...@@ -3669,7 +3669,10 @@ fn indexablePtrLenOrNone(
3669 const zcu = pt.zcu;3669 const zcu = pt.zcu;
3670 const operand_ty = sema.typeOf(operand);3670 const operand_ty = sema.typeOf(operand);
3671 try checkMemOperand(sema, block, src, operand_ty);3671 try checkMemOperand(sema, block, src, operand_ty);
3672 if (operand_ty.ptrSize(zcu) == .many) return .none;3672 switch (operand_ty.ptrSize(zcu)) {
3673 .many, .c => return .none,
3674 .one, .slice => {},
3675 }
3673 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);3676 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
3674 return sema.fieldVal(block, src, operand, field_name, src);3677 return sema.fieldVal(block, src, operand, field_name, src);
3675}3678}
test/behavior/memcpy.zig+21
...@@ -69,6 +69,27 @@ fn testMemcpyDestManyPtr() !void {...@@ -69,6 +69,27 @@ fn testMemcpyDestManyPtr() !void {
69 try expect(buf[4] == 'o');69 try expect(buf[4] == 'o');
70}70}
7171
72test "@memcpy C pointer" {
73 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
74 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
75 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
76 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
77
78 try testMemcpyCPointer();
79 try comptime testMemcpyCPointer();
80}
81
82fn testMemcpyCPointer() !void {
83 const src = "hello";
84 var buf: [5]u8 = undefined;
85 @memcpy(@as([*c]u8, &buf), src);
86 try expect(buf[0] == 'h');
87 try expect(buf[1] == 'e');
88 try expect(buf[2] == 'l');
89 try expect(buf[3] == 'l');
90 try expect(buf[4] == 'o');
91}
92
72test "@memcpy slice" {93test "@memcpy slice" {
73 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;94 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
74 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;95 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;