diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-01-14 23:05:33 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-01-14 23:08:11 -0700 |
| commit | 41f3799bf0cfc8241f458094781ba45967e2576e (patch) | |
| tree | b26beee8643ba7ebac7774898366f6add4667e3b | |
| parent | ba0f72363accc19edbfc5a7ae42d5a8970f56f64 (diff) | |
| download | zig-41f3799bf0cfc8241f458094781ba45967e2576e.tar.gz zig-41f3799bf0cfc8241f458094781ba45967e2576e.zip | |
Sema: fix array_init with runtime element
Previously it emitted an invalid AIR encoding.
| -rw-r--r-- | src/Sema.zig | 23 | ||||
| -rw-r--r-- | src/type.zig | 1 | ||||
| -rw-r--r-- | test/behavior/array_llvm.zig | 42 | ||||
| -rw-r--r-- | test/behavior/array_stage1.zig | 40 |
4 files changed, 63 insertions, 43 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 7504352576..563b1d5096 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -367,10 +367,20 @@ pub const Block = struct { elem_index: Air.Inst.Ref, elem_ptr_ty: Type, ) !Air.Inst.Ref { + const ty_ref = try block.sema.addType(elem_ptr_ty); + return block.addPtrElemPtrTypeRef(array_ptr, elem_index, ty_ref); + } + + pub fn addPtrElemPtrTypeRef( + block: *Block, + array_ptr: Air.Inst.Ref, + elem_index: Air.Inst.Ref, + elem_ptr_ty: Air.Inst.Ref, + ) !Air.Inst.Ref { return block.addInst(.{ .tag = .ptr_elem_ptr, .data = .{ .ty_pl = .{ - .ty = try block.sema.addType(elem_ptr_ty), + .ty = elem_ptr_ty, .payload = try block.sema.addExtra(Air.Bin{ .lhs = array_ptr, .rhs = elem_index, @@ -10538,9 +10548,16 @@ fn zirArrayInit( }); const alloc = try block.addTy(.alloc, alloc_ty); + const elem_ptr_ty = try Type.ptr(sema.arena, .{ + .mutable = true, + .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + .pointee_type = elem_ty, + }); + const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); + for (resolved_args) |arg, i| { - const index = try sema.addIntUnsigned(Type.initTag(.u64), i); - const elem_ptr = try block.addBinOp(.ptr_elem_ptr, alloc, index); + const index = try sema.addIntUnsigned(Type.u64, i); + const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref); _ = try block.addBinOp(.store, elem_ptr, arg); } if (is_ref) { diff --git a/src/type.zig b/src/type.zig index b759a4bc34..e14c81f707 100644 --- a/src/type.zig +++ b/src/type.zig @@ -4511,6 +4511,7 @@ pub const Type = extern union { pub const @"u8" = initTag(.u8); pub const @"u32" = initTag(.u32); + pub const @"u64" = initTag(.u64); pub const @"bool" = initTag(.bool); pub const @"usize" = initTag(.usize); pub const @"isize" = initTag(.isize); diff --git a/test/behavior/array_llvm.zig b/test/behavior/array_llvm.zig index 3fca269034..a828954b73 100644 --- a/test/behavior/array_llvm.zig +++ b/test/behavior/array_llvm.zig @@ -45,3 +45,45 @@ fn testImplicitCastSingleItemPtr() !void { slice[0] += 1; try expect(byte == 101); } + +fn testArrayByValAtComptime(b: [2]u8) u8 { + return b[0]; +} + +test "comptime evaluating function that takes array by value" { + const arr = [_]u8{ 1, 2 }; + const x = comptime testArrayByValAtComptime(arr); + const y = comptime testArrayByValAtComptime(arr); + try expect(x == 1); + try expect(y == 1); +} + +test "runtime initialize array elem and then implicit cast to slice" { + var two: i32 = 2; + const x: []const i32 = &[_]i32{two}; + try expect(x[0] == 2); +} + +test "array literal as argument to function" { + const S = struct { + fn entry(two: i32) !void { + try foo(&[_]i32{ 1, 2, 3 }); + try foo(&[_]i32{ 1, two, 3 }); + try foo2(true, &[_]i32{ 1, 2, 3 }); + try foo2(true, &[_]i32{ 1, two, 3 }); + } + fn foo(x: []const i32) !void { + try expect(x[0] == 1); + try expect(x[1] == 2); + try expect(x[2] == 3); + } + fn foo2(trash: bool, x: []const i32) !void { + try expect(trash); + try expect(x[0] == 1); + try expect(x[1] == 2); + try expect(x[2] == 3); + } + }; + try S.entry(2); + comptime try S.entry(2); +} diff --git a/test/behavior/array_stage1.zig b/test/behavior/array_stage1.zig index d4b9221fe0..daef20ffb5 100644 --- a/test/behavior/array_stage1.zig +++ b/test/behavior/array_stage1.zig @@ -4,46 +4,6 @@ const mem = std.mem; const expect = testing.expect; const expectEqual = testing.expectEqual; -fn testArrayByValAtComptime(b: [2]u8) u8 { - return b[0]; -} - -test "comptime evaluating function that takes array by value" { - const arr = [_]u8{ 0, 1 }; - _ = comptime testArrayByValAtComptime(arr); - _ = comptime testArrayByValAtComptime(arr); -} - -test "runtime initialize array elem and then implicit cast to slice" { - var two: i32 = 2; - const x: []const i32 = &[_]i32{two}; - try expect(x[0] == 2); -} - -test "array literal as argument to function" { - const S = struct { - fn entry(two: i32) !void { - try foo(&[_]i32{ 1, 2, 3 }); - try foo(&[_]i32{ 1, two, 3 }); - try foo2(true, &[_]i32{ 1, 2, 3 }); - try foo2(true, &[_]i32{ 1, two, 3 }); - } - fn foo(x: []const i32) !void { - try expect(x[0] == 1); - try expect(x[1] == 2); - try expect(x[2] == 3); - } - fn foo2(trash: bool, x: []const i32) !void { - try expect(trash); - try expect(x[0] == 1); - try expect(x[1] == 2); - try expect(x[2] == 3); - } - }; - try S.entry(2); - comptime try S.entry(2); -} - test "double nested array to const slice cast in array literal" { const S = struct { fn entry(two: i32) !void { |
