authorgravatar for 51252236+xdBronch@users.noreply.github.comxdBronch <51252236+xdBronch@users.noreply.github.com> 2025-03-09 23:03:06-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-04-28 05:09:12+01:00
log410298271eae2535e39a9de433afc8159704e7c6
treea98ab5298b927af1933654893396e57827fc19c6
parent78df3c9301891a3333eb5420074c9b0d56d54a54

Sema: fix memcpy with C pointers


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

src/Sema.zig+4-1
...@@ -3668,7 +3668,10 @@ fn indexablePtrLenOrNone(...@@ -3668,7 +3668,10 @@ fn indexablePtrLenOrNone(
3668 const zcu = pt.zcu;3668 const zcu = pt.zcu;
3669 const operand_ty = sema.typeOf(operand);3669 const operand_ty = sema.typeOf(operand);
3670 try checkMemOperand(sema, block, src, operand_ty);3670 try checkMemOperand(sema, block, src, operand_ty);
3671 if (operand_ty.ptrSize(zcu) == .many) return .none;3671 switch (operand_ty.ptrSize(zcu)) {
3672 .many, .c => return .none,
3673 .one, .slice => {},
3674 }
3672 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);3675 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
3673 return sema.fieldVal(block, src, operand, field_name, src);3676 return sema.fieldVal(block, src, operand, field_name, src);
3674}3677}
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;