Commit 410298271e

xdBronch <51252236+xdBronch@users.noreply.github.com>
2025-03-10 04:03:06
Sema: fix memcpy with C pointers
1 parent 78df3c9
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -3668,7 +3668,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);
 }
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;