authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-23 09:45:08-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-12-23 09:45:08-08:00
logbb0f7d55e8c50e379fa9bdcb8758d89d08e0cc1f
treea32c2299fce64c4c2364038743fe4d21355f7faa
parent1b0e913e0fcc63b48778be300b0705ceb1fd84f1
parent5c2897e89fd4730cf18a78d23524bd74cef93962
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #18347 from jacobly0/slice_ptr-type

Sema: ensure `slice_ptr` produces the correct type

3 files changed, 30 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 {
src/link/C.zig+2
...@@ -136,6 +136,8 @@ pub fn deinit(self: *C) void {...@@ -136,6 +136,8 @@ pub fn deinit(self: *C) void {
136 self.string_bytes.deinit(gpa);136 self.string_bytes.deinit(gpa);
137 self.fwd_decl_buf.deinit(gpa);137 self.fwd_decl_buf.deinit(gpa);
138 self.code_buf.deinit(gpa);138 self.code_buf.deinit(gpa);
139 self.lazy_fwd_decl_buf.deinit(gpa);
140 self.lazy_code_buf.deinit(gpa);
139}141}
140142
141pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void {143pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) 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,