authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-14 23:05:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-14 23:08:11-07:00
log41f3799bf0cfc8241f458094781ba45967e2576e
treeb26beee8643ba7ebac7774898366f6add4667e3b
parentba0f72363accc19edbfc5a7ae42d5a8970f56f64

Sema: fix array_init with runtime element

Previously it emitted an invalid AIR encoding.

4 files changed, 63 insertions(+), 43 deletions(-)

src/Sema.zig+20-3
...@@ -366,11 +366,21 @@ pub const Block = struct {...@@ -366,11 +366,21 @@ pub const Block = struct {
366 array_ptr: Air.Inst.Ref,366 array_ptr: Air.Inst.Ref,
367 elem_index: Air.Inst.Ref,367 elem_index: Air.Inst.Ref,
368 elem_ptr_ty: Type,368 elem_ptr_ty: Type,
369 ) !Air.Inst.Ref {
370 const ty_ref = try block.sema.addType(elem_ptr_ty);
371 return block.addPtrElemPtrTypeRef(array_ptr, elem_index, ty_ref);
372 }
373
374 pub fn addPtrElemPtrTypeRef(
375 block: *Block,
376 array_ptr: Air.Inst.Ref,
377 elem_index: Air.Inst.Ref,
378 elem_ptr_ty: Air.Inst.Ref,
369 ) !Air.Inst.Ref {379 ) !Air.Inst.Ref {
370 return block.addInst(.{380 return block.addInst(.{
371 .tag = .ptr_elem_ptr,381 .tag = .ptr_elem_ptr,
372 .data = .{ .ty_pl = .{382 .data = .{ .ty_pl = .{
373 .ty = try block.sema.addType(elem_ptr_ty),383 .ty = elem_ptr_ty,
374 .payload = try block.sema.addExtra(Air.Bin{384 .payload = try block.sema.addExtra(Air.Bin{
375 .lhs = array_ptr,385 .lhs = array_ptr,
376 .rhs = elem_index,386 .rhs = elem_index,
...@@ -10538,9 +10548,16 @@ fn zirArrayInit(...@@ -10538,9 +10548,16 @@ fn zirArrayInit(
10538 });10548 });
10539 const alloc = try block.addTy(.alloc, alloc_ty);10549 const alloc = try block.addTy(.alloc, alloc_ty);
1054010550
10551 const elem_ptr_ty = try Type.ptr(sema.arena, .{
10552 .mutable = true,
10553 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
10554 .pointee_type = elem_ty,
10555 });
10556 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
10557
10541 for (resolved_args) |arg, i| {10558 for (resolved_args) |arg, i| {
10542 const index = try sema.addIntUnsigned(Type.initTag(.u64), i);10559 const index = try sema.addIntUnsigned(Type.u64, i);
10543 const elem_ptr = try block.addBinOp(.ptr_elem_ptr, alloc, index);10560 const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref);
10544 _ = try block.addBinOp(.store, elem_ptr, arg);10561 _ = try block.addBinOp(.store, elem_ptr, arg);
10545 }10562 }
10546 if (is_ref) {10563 if (is_ref) {
src/type.zig+1
...@@ -4511,6 +4511,7 @@ pub const Type = extern union {...@@ -4511,6 +4511,7 @@ pub const Type = extern union {
45114511
4512 pub const @"u8" = initTag(.u8);4512 pub const @"u8" = initTag(.u8);
4513 pub const @"u32" = initTag(.u32);4513 pub const @"u32" = initTag(.u32);
4514 pub const @"u64" = initTag(.u64);
4514 pub const @"bool" = initTag(.bool);4515 pub const @"bool" = initTag(.bool);
4515 pub const @"usize" = initTag(.usize);4516 pub const @"usize" = initTag(.usize);
4516 pub const @"isize" = initTag(.isize);4517 pub const @"isize" = initTag(.isize);
test/behavior/array_llvm.zig+42
...@@ -45,3 +45,45 @@ fn testImplicitCastSingleItemPtr() !void {...@@ -45,3 +45,45 @@ fn testImplicitCastSingleItemPtr() !void {
45 slice[0] += 1;45 slice[0] += 1;
46 try expect(byte == 101);46 try expect(byte == 101);
47}47}
48
49fn testArrayByValAtComptime(b: [2]u8) u8 {
50 return b[0];
51}
52
53test "comptime evaluating function that takes array by value" {
54 const arr = [_]u8{ 1, 2 };
55 const x = comptime testArrayByValAtComptime(arr);
56 const y = comptime testArrayByValAtComptime(arr);
57 try expect(x == 1);
58 try expect(y == 1);
59}
60
61test "runtime initialize array elem and then implicit cast to slice" {
62 var two: i32 = 2;
63 const x: []const i32 = &[_]i32{two};
64 try expect(x[0] == 2);
65}
66
67test "array literal as argument to function" {
68 const S = struct {
69 fn entry(two: i32) !void {
70 try foo(&[_]i32{ 1, 2, 3 });
71 try foo(&[_]i32{ 1, two, 3 });
72 try foo2(true, &[_]i32{ 1, 2, 3 });
73 try foo2(true, &[_]i32{ 1, two, 3 });
74 }
75 fn foo(x: []const i32) !void {
76 try expect(x[0] == 1);
77 try expect(x[1] == 2);
78 try expect(x[2] == 3);
79 }
80 fn foo2(trash: bool, x: []const i32) !void {
81 try expect(trash);
82 try expect(x[0] == 1);
83 try expect(x[1] == 2);
84 try expect(x[2] == 3);
85 }
86 };
87 try S.entry(2);
88 comptime try S.entry(2);
89}
test/behavior/array_stage1.zig-40
...@@ -4,46 +4,6 @@ const mem = std.mem;...@@ -4,46 +4,6 @@ const mem = std.mem;
4const expect = testing.expect;4const expect = testing.expect;
5const expectEqual = testing.expectEqual;5const expectEqual = testing.expectEqual;
66
7fn testArrayByValAtComptime(b: [2]u8) u8 {
8 return b[0];
9}
10
11test "comptime evaluating function that takes array by value" {
12 const arr = [_]u8{ 0, 1 };
13 _ = comptime testArrayByValAtComptime(arr);
14 _ = comptime testArrayByValAtComptime(arr);
15}
16
17test "runtime initialize array elem and then implicit cast to slice" {
18 var two: i32 = 2;
19 const x: []const i32 = &[_]i32{two};
20 try expect(x[0] == 2);
21}
22
23test "array literal as argument to function" {
24 const S = struct {
25 fn entry(two: i32) !void {
26 try foo(&[_]i32{ 1, 2, 3 });
27 try foo(&[_]i32{ 1, two, 3 });
28 try foo2(true, &[_]i32{ 1, 2, 3 });
29 try foo2(true, &[_]i32{ 1, two, 3 });
30 }
31 fn foo(x: []const i32) !void {
32 try expect(x[0] == 1);
33 try expect(x[1] == 2);
34 try expect(x[2] == 3);
35 }
36 fn foo2(trash: bool, x: []const i32) !void {
37 try expect(trash);
38 try expect(x[0] == 1);
39 try expect(x[1] == 2);
40 try expect(x[2] == 3);
41 }
42 };
43 try S.entry(2);
44 comptime try S.entry(2);
45}
46
47test "double nested array to const slice cast in array literal" {7test "double nested array to const slice cast in array literal" {
48 const S = struct {8 const S = struct {
49 fn entry(two: i32) !void {9 fn entry(two: i32) !void {