authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-12-23 02:08:58-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-12-23 02:08:58-05:00
logd312665803c1535da6f36387183bbb2348e4216c
tree8b818933ed8041d44e2c6dedd634785401478d62
parent21ae64852a531c36ae3166aa2b6f1fbaaf76c6f9

Sema: ensure `slice_ptr` produces the correct type

Closes #18345

2 files changed, 28 insertions(+), 5 deletions(-)

src/Sema.zig+7-5
...@@ -24311,7 +24311,8 @@ fn analyzeMinMax(...@@ -24311,7 +24311,8 @@ fn analyzeMinMax(
2431124311
24312fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {24312fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref {
24313 const mod = sema.mod;24313 const mod = sema.mod;
24314 const info = sema.typeOf(ptr).ptrInfo(mod);24314 const ptr_ty = sema.typeOf(ptr);
24315 const info = ptr_ty.ptrInfo(mod);
24315 if (info.flags.size == .One) {24316 if (info.flags.size == .One) {
24316 // Already an array pointer.24317 // Already an array pointer.
24317 return ptr;24318 return ptr;
...@@ -24330,10 +24331,11 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A...@@ -24330,10 +24331,11 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A
24330 .address_space = info.flags.address_space,24331 .address_space = info.flags.address_space,
24331 },24332 },
24332 });24333 });
24333 if (info.flags.size == .Slice) {24334 const non_slice_ptr = if (info.flags.size == .Slice)
24334 return block.addTyOp(.slice_ptr, new_ty, ptr);24335 try block.addTyOp(.slice_ptr, ptr_ty.slicePtrFieldType(mod), ptr)
24335 }24336 else
24336 return block.addBitCast(new_ty, ptr);24337 ptr;
24338 return block.addBitCast(new_ty, non_slice_ptr);
24337}24339}
2433824340
24339fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {24341fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
test/behavior/memcpy.zig+21
...@@ -66,6 +66,27 @@ fn testMemcpyDestManyPtr() !void {...@@ -66,6 +66,27 @@ fn testMemcpyDestManyPtr() !void {
66 try expect(buf[4] == 'o');66 try expect(buf[4] == 'o');
67}67}
6868
69test "@memcpy slice" {
70 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
71 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
72 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
73
74 try testMemcpySlice();
75 try comptime testMemcpySlice();
76}
77
78fn testMemcpySlice() !void {
79 var buf: [5]u8 = undefined;
80 const dst: []u8 = &buf;
81 const src: []const u8 = "hello";
82 @memcpy(dst, src);
83 try expect(buf[0] == 'h');
84 try expect(buf[1] == 'e');
85 try expect(buf[2] == 'l');
86 try expect(buf[3] == 'l');
87 try expect(buf[4] == 'o');
88}
89
69comptime {90comptime {
70 const S = struct {91 const S = struct {
71 buffer: [8]u8 = undefined,92 buffer: [8]u8 = undefined,