Commit d312665803

Jacob Young <jacobly0@users.noreply.github.com>
2023-12-23 08:08:58
Sema: ensure `slice_ptr` produces the correct type
Closes #18345
1 parent 21ae648
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -24311,7 +24311,8 @@ fn analyzeMinMax(
 
 fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
     const mod = sema.mod;
-    const info = sema.typeOf(ptr).ptrInfo(mod);
+    const ptr_ty = sema.typeOf(ptr);
+    const info = ptr_ty.ptrInfo(mod);
     if (info.flags.size == .One) {
         // Already an array pointer.
         return ptr;
@@ -24330,10 +24331,11 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A
             .address_space = info.flags.address_space,
         },
     });
-    if (info.flags.size == .Slice) {
-        return block.addTyOp(.slice_ptr, new_ty, ptr);
-    }
-    return block.addBitCast(new_ty, ptr);
+    const non_slice_ptr = if (info.flags.size == .Slice)
+        try block.addTyOp(.slice_ptr, ptr_ty.slicePtrFieldType(mod), ptr)
+    else
+        ptr;
+    return block.addBitCast(new_ty, non_slice_ptr);
 }
 
 fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
test/behavior/memcpy.zig
@@ -66,6 +66,27 @@ fn testMemcpyDestManyPtr() !void {
     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;
+    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
+
+    try testMemcpySlice();
+    try comptime testMemcpySlice();
+}
+
+fn testMemcpySlice() !void {
+    var buf: [5]u8 = undefined;
+    const dst: []u8 = &buf;
+    const src: []const u8 = "hello";
+    @memcpy(dst, 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');
+}
+
 comptime {
     const S = struct {
         buffer: [8]u8 = undefined,