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(
36683668 const zcu = pt.zcu;
36693669 const operand_ty = sema.typeOf(operand);
36703670 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 }
36723675 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "len", .no_embedded_nulls);
36733676 return sema.fieldVal(block, src, operand, field_name, src);
36743677}
test/behavior/memcpy.zig+21
......@@ -69,6 +69,27 @@ fn testMemcpyDestManyPtr() !void {
6969 try expect(buf[4] == 'o');
7070}
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
7293test "@memcpy slice" {
7394 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7495 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;