aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-01-14 23:05:33 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-01-14 23:08:11 -0700
commit41f3799bf0cfc8241f458094781ba45967e2576e (patch)
treeb26beee8643ba7ebac7774898366f6add4667e3b
parentba0f72363accc19edbfc5a7ae42d5a8970f56f64 (diff)
downloadzig-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.zig23
-rw-r--r--src/type.zig1
-rw-r--r--test/behavior/array_llvm.zig42
-rw-r--r--test/behavior/array_stage1.zig40
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 {