authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-14 10:12:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-14 10:12:45-07:00
log25874747174da2b0e77b3b888d0f5a13aa1a317e
treef715cc1f2ce49c747e2e045e785673d41af3b312
parent07397707392d27fbee5f1bf0a788937b66300bf0

stage2: progress towards stage3

* The `@bitCast` workaround is removed in favor of `@ptrCast` properly doing element casting for slice element types. This required an enhancement both to stage1 and stage2. * stage1 incorrectly accepts `.{}` instead of `{}`. stage2 code that abused this is fixed. * Make some parameters comptime to support functions in switch expressions (as opposed to making them function pointers). * Avoid relying on local temporaries being mutable. * Workarounds for when stage1 and stage2 disagree on function pointer types. * Workaround recursive formatting bug with a `@panic("TODO")`. * Remove unreachable `else` prongs for some inferred error sets. All in effort towards #89.

26 files changed, 156 insertions(+), 91 deletions(-)

lib/std/fmt.zig-2
...@@ -766,12 +766,10 @@ fn formatFloatValue(...@@ -766,12 +766,10 @@ fn formatFloatValue(
766 } else if (comptime std.mem.eql(u8, fmt, "d")) {766 } else if (comptime std.mem.eql(u8, fmt, "d")) {
767 formatFloatDecimal(value, options, buf_stream.writer()) catch |err| switch (err) {767 formatFloatDecimal(value, options, buf_stream.writer()) catch |err| switch (err) {
768 error.NoSpaceLeft => unreachable,768 error.NoSpaceLeft => unreachable,
769 else => |e| return e,
770 };769 };
771 } else if (comptime std.mem.eql(u8, fmt, "x")) {770 } else if (comptime std.mem.eql(u8, fmt, "x")) {
772 formatFloatHexadecimal(value, options, buf_stream.writer()) catch |err| switch (err) {771 formatFloatHexadecimal(value, options, buf_stream.writer()) catch |err| switch (err) {
773 error.NoSpaceLeft => unreachable,772 error.NoSpaceLeft => unreachable,
774 else => |e| return e,
775 };773 };
776 } else {774 } else {
777 @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");775 @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
lib/std/io.zig-1
...@@ -9,7 +9,6 @@ const os = std.os;...@@ -9,7 +9,6 @@ const os = std.os;
9const fs = std.fs;9const fs = std.fs;
10const mem = std.mem;10const mem = std.mem;
11const meta = std.meta;11const meta = std.meta;
12const trait = meta.trait;
13const File = std.fs.File;12const File = std.fs.File;
1413
15pub const Mode = enum {14pub const Mode = enum {
lib/std/rand.zig+1-3
...@@ -66,9 +66,7 @@ pub const Random = struct {...@@ -66,9 +66,7 @@ pub const Random = struct {
6666
67 /// Returns a random value from an enum, evenly distributed.67 /// Returns a random value from an enum, evenly distributed.
68 pub fn enumValue(r: Random, comptime EnumType: type) EnumType {68 pub fn enumValue(r: Random, comptime EnumType: type) EnumType {
69 if (comptime !std.meta.trait.is(.Enum)(EnumType)) {69 comptime assert(@typeInfo(EnumType) == .Enum);
70 @compileError("Random.enumValue requires an enum type, not a " ++ @typeName(EnumType));
71 }
7270
73 // We won't use int -> enum casting because enum elements can have71 // We won't use int -> enum casting because enum elements can have
74 // arbitrary values. Instead we'll randomly pick one of the type's values.72 // arbitrary values. Instead we'll randomly pick one of the type's values.
src/AstGen.zig+2-2
...@@ -85,12 +85,12 @@ fn reserveExtra(astgen: *AstGen, size: usize) Allocator.Error!u32 {...@@ -85,12 +85,12 @@ fn reserveExtra(astgen: *AstGen, size: usize) Allocator.Error!u32 {
85}85}
8686
87fn appendRefs(astgen: *AstGen, refs: []const Zir.Inst.Ref) !void {87fn appendRefs(astgen: *AstGen, refs: []const Zir.Inst.Ref) !void {
88 const coerced = @bitCast([]const u32, refs);88 const coerced = @ptrCast([]const u32, refs);
89 return astgen.extra.appendSlice(astgen.gpa, coerced);89 return astgen.extra.appendSlice(astgen.gpa, coerced);
90}90}
9191
92fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {92fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void {
93 const coerced = @bitCast([]const u32, refs);93 const coerced = @ptrCast([]const u32, refs);
94 astgen.extra.appendSliceAssumeCapacity(coerced);94 astgen.extra.appendSliceAssumeCapacity(coerced);
95}95}
9696
src/Liveness.zig+4-4
...@@ -454,7 +454,7 @@ fn analyzeInst(...@@ -454,7 +454,7 @@ fn analyzeInst(
454 const inst_data = inst_datas[inst].pl_op;454 const inst_data = inst_datas[inst].pl_op;
455 const callee = inst_data.operand;455 const callee = inst_data.operand;
456 const extra = a.air.extraData(Air.Call, inst_data.payload);456 const extra = a.air.extraData(Air.Call, inst_data.payload);
457 const args = @bitCast([]const Air.Inst.Ref, a.air.extra[extra.end..][0..extra.data.args_len]);457 const args = @ptrCast([]const Air.Inst.Ref, a.air.extra[extra.end..][0..extra.data.args_len]);
458 if (args.len + 1 <= bpi - 1) {458 if (args.len + 1 <= bpi - 1) {
459 var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1);459 var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1);
460 buf[0] = callee;460 buf[0] = callee;
...@@ -495,7 +495,7 @@ fn analyzeInst(...@@ -495,7 +495,7 @@ fn analyzeInst(
495 const ty_pl = inst_datas[inst].ty_pl;495 const ty_pl = inst_datas[inst].ty_pl;
496 const aggregate_ty = a.air.getRefType(ty_pl.ty);496 const aggregate_ty = a.air.getRefType(ty_pl.ty);
497 const len = @intCast(usize, aggregate_ty.arrayLen());497 const len = @intCast(usize, aggregate_ty.arrayLen());
498 const elements = @bitCast([]const Air.Inst.Ref, a.air.extra[ty_pl.payload..][0..len]);498 const elements = @ptrCast([]const Air.Inst.Ref, a.air.extra[ty_pl.payload..][0..len]);
499499
500 if (elements.len <= bpi - 1) {500 if (elements.len <= bpi - 1) {
501 var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1);501 var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1);
...@@ -571,9 +571,9 @@ fn analyzeInst(...@@ -571,9 +571,9 @@ fn analyzeInst(
571 .assembly => {571 .assembly => {
572 const extra = a.air.extraData(Air.Asm, inst_datas[inst].ty_pl.payload);572 const extra = a.air.extraData(Air.Asm, inst_datas[inst].ty_pl.payload);
573 var extra_i: usize = extra.end;573 var extra_i: usize = extra.end;
574 const outputs = @bitCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.outputs_len]);574 const outputs = @ptrCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.outputs_len]);
575 extra_i += outputs.len;575 extra_i += outputs.len;
576 const inputs = @bitCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.inputs_len]);576 const inputs = @ptrCast([]const Air.Inst.Ref, a.air.extra[extra_i..][0..extra.data.inputs_len]);
577 extra_i += inputs.len;577 extra_i += inputs.len;
578578
579 simple: {579 simple: {
src/Module.zig+2-2
...@@ -4593,7 +4593,7 @@ pub fn clearDecl(...@@ -4593,7 +4593,7 @@ pub fn clearDecl(
4593 .c => .{ .c = {} },4593 .c => .{ .c = {} },
4594 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },4594 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
4595 .spirv => .{ .spirv = .{} },4595 .spirv => .{ .spirv = .{} },
4596 .nvptx => .{ .nvptx = .{} },4596 .nvptx => .{ .nvptx = {} },
4597 };4597 };
4598 }4598 }
4599 if (decl.getInnerNamespace()) |namespace| {4599 if (decl.getInnerNamespace()) |namespace| {
...@@ -4975,7 +4975,7 @@ pub fn allocateNewDecl(...@@ -4975,7 +4975,7 @@ pub fn allocateNewDecl(
4975 .c => .{ .c = {} },4975 .c => .{ .c = {} },
4976 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },4976 .wasm => .{ .wasm = link.File.Wasm.FnData.empty },
4977 .spirv => .{ .spirv = .{} },4977 .spirv => .{ .spirv = .{} },
4978 .nvptx => .{ .nvptx = .{} },4978 .nvptx => .{ .nvptx = {} },
4979 },4979 },
4980 .generation = 0,4980 .generation = 0,
4981 .is_pub = false,4981 .is_pub = false,
src/Sema.zig+25-9
...@@ -14110,21 +14110,27 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -14110,21 +14110,27 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1411014110
14111 try sema.checkPtrType(block, dest_ty_src, dest_ty);14111 try sema.checkPtrType(block, dest_ty_src, dest_ty);
14112 try sema.checkPtrOperand(block, operand_src, operand_ty);14112 try sema.checkPtrOperand(block, operand_src, operand_ty);
14113 if (dest_ty.isSlice()) {14113
14114 const dest_is_slice = dest_ty.isSlice();
14115 const operand_is_slice = operand_ty.isSlice();
14116 if (dest_is_slice and !operand_is_slice) {
14114 return sema.fail(block, dest_ty_src, "illegal pointer cast to slice", .{});14117 return sema.fail(block, dest_ty_src, "illegal pointer cast to slice", .{});
14115 }14118 }
14116 const ptr = if (operand_ty.isSlice())14119 const ptr = if (operand_is_slice and !dest_is_slice)
14117 try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty)14120 try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty)
14118 else14121 else
14119 operand;14122 operand;
1412014123
14121 try sema.resolveTypeLayout(block, dest_ty_src, dest_ty.elemType2());14124 const dest_elem_ty = dest_ty.elemType2();
14125 try sema.resolveTypeLayout(block, dest_ty_src, dest_elem_ty);
14122 const dest_align = dest_ty.ptrAlignment(target);14126 const dest_align = dest_ty.ptrAlignment(target);
14123 try sema.resolveTypeLayout(block, operand_src, operand_ty.elemType2());14127
14128 const operand_elem_ty = operand_ty.elemType2();
14129 try sema.resolveTypeLayout(block, operand_src, operand_elem_ty);
14124 const operand_align = operand_ty.ptrAlignment(target);14130 const operand_align = operand_ty.ptrAlignment(target);
1412514131
14126 // If the destination is less aligned than the source, preserve the source alignment14132 // If the destination is less aligned than the source, preserve the source alignment
14127 var aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {14133 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
14128 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result14134 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result
14129 if (dest_ty.zigTypeTag() == .Optional) {14135 if (dest_ty.zigTypeTag() == .Optional) {
14130 var buf: Type.Payload.ElemType = undefined;14136 var buf: Type.Payload.ElemType = undefined;
...@@ -14138,6 +14144,16 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -14138,6 +14144,16 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
14138 }14144 }
14139 };14145 };
1414014146
14147 if (dest_is_slice) {
14148 const operand_elem_size = operand_elem_ty.abiSize(target);
14149 const dest_elem_size = dest_elem_ty.abiSize(target);
14150 if (operand_elem_size != dest_elem_size) {
14151 // note that this is not implemented in stage1 so we should probably wait
14152 // until that codebase is replaced before implementing this in stage2.
14153 return sema.fail(block, dest_ty_src, "TODO: implement @ptrCast between slices changing the length", .{});
14154 }
14155 }
14156
14141 return sema.coerceCompatiblePtrs(block, aligned_dest_ty, ptr, operand_src);14157 return sema.coerceCompatiblePtrs(block, aligned_dest_ty, ptr, operand_src);
14142}14158}
1414314159
...@@ -15743,7 +15759,7 @@ fn zirMinMax(...@@ -15743,7 +15759,7 @@ fn zirMinMax(
15743 sema: *Sema,15759 sema: *Sema,
15744 block: *Block,15760 block: *Block,
15745 inst: Zir.Inst.Index,15761 inst: Zir.Inst.Index,
15746 air_tag: Air.Inst.Tag,15762 comptime air_tag: Air.Inst.Tag,
15747) CompileError!Air.Inst.Ref {15763) CompileError!Air.Inst.Ref {
15748 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;15764 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
15749 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;15765 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
...@@ -15763,7 +15779,7 @@ fn analyzeMinMax(...@@ -15763,7 +15779,7 @@ fn analyzeMinMax(
15763 src: LazySrcLoc,15779 src: LazySrcLoc,
15764 lhs: Air.Inst.Ref,15780 lhs: Air.Inst.Ref,
15765 rhs: Air.Inst.Ref,15781 rhs: Air.Inst.Ref,
15766 air_tag: Air.Inst.Tag,15782 comptime air_tag: Air.Inst.Tag,
15767 lhs_src: LazySrcLoc,15783 lhs_src: LazySrcLoc,
15768 rhs_src: LazySrcLoc,15784 rhs_src: LazySrcLoc,
15769) CompileError!Air.Inst.Ref {15785) CompileError!Air.Inst.Ref {
...@@ -20976,7 +20992,7 @@ fn resolvePeerTypes(...@@ -20976,7 +20992,7 @@ fn resolvePeerTypes(
20976 sema: *Sema,20992 sema: *Sema,
20977 block: *Block,20993 block: *Block,
20978 src: LazySrcLoc,20994 src: LazySrcLoc,
20979 instructions: []Air.Inst.Ref,20995 instructions: []const Air.Inst.Ref,
20980 candidate_srcs: Module.PeerTypeCandidateSrc,20996 candidate_srcs: Module.PeerTypeCandidateSrc,
20981) !Type {20997) !Type {
20982 switch (instructions.len) {20998 switch (instructions.len) {
...@@ -22794,7 +22810,7 @@ pub fn addExtraAssumeCapacity(sema: *Sema, extra: anytype) u32 {...@@ -22794,7 +22810,7 @@ pub fn addExtraAssumeCapacity(sema: *Sema, extra: anytype) u32 {
22794}22810}
2279522811
22796fn appendRefsAssumeCapacity(sema: *Sema, refs: []const Air.Inst.Ref) void {22812fn appendRefsAssumeCapacity(sema: *Sema, refs: []const Air.Inst.Ref) void {
22797 const coerced = @bitCast([]const u32, refs);22813 const coerced = @ptrCast([]const u32, refs);
22798 sema.air_extra.appendSliceAssumeCapacity(coerced);22814 sema.air_extra.appendSliceAssumeCapacity(coerced);
22799}22815}
2280022816
src/arch/aarch64/CodeGen.zig+8-5
...@@ -2398,7 +2398,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -2398,7 +2398,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
2398 const pl_op = self.air.instructions.items(.data)[inst].pl_op;2398 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
2399 const callee = pl_op.operand;2399 const callee = pl_op.operand;
2400 const extra = self.air.extraData(Air.Call, pl_op.payload);2400 const extra = self.air.extraData(Air.Call, pl_op.payload);
2401 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);2401 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
2402 const ty = self.air.typeOf(callee);2402 const ty = self.air.typeOf(callee);
24032403
2404 const fn_ty = switch (ty.zigTypeTag()) {2404 const fn_ty = switch (ty.zigTypeTag()) {
...@@ -2865,7 +2865,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2865,7 +2865,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
2865 // TODO track the new register / stack allocation2865 // TODO track the new register / stack allocation
2866 }2866 }
28672867
2868 self.branch_stack.pop().deinit(self.gpa);2868 {
2869 var item = self.branch_stack.pop();
2870 item.deinit(self.gpa);
2871 }
28692872
2870 // We already took care of pl_op.operand earlier, so we're going2873 // We already took care of pl_op.operand earlier, so we're going
2871 // to pass .none here2874 // to pass .none here
...@@ -3162,9 +3165,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -3162,9 +3165,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
3162 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;3165 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
3163 const clobbers_len = @truncate(u31, extra.data.flags);3166 const clobbers_len = @truncate(u31, extra.data.flags);
3164 var extra_i: usize = extra.end;3167 var extra_i: usize = extra.end;
3165 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);3168 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
3166 extra_i += outputs.len;3169 extra_i += outputs.len;
3167 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);3170 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
3168 extra_i += inputs.len;3171 extra_i += inputs.len;
31693172
3170 const dead = !is_volatile and self.liveness.isUnused(inst);3173 const dead = !is_volatile and self.liveness.isUnused(inst);
...@@ -3686,7 +3689,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -3686,7 +3689,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
3686 const vector_ty = self.air.typeOfIndex(inst);3689 const vector_ty = self.air.typeOfIndex(inst);
3687 const len = vector_ty.vectorLen();3690 const len = vector_ty.vectorLen();
3688 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3691 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3689 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);3692 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
3690 const result: MCValue = res: {3693 const result: MCValue = res: {
3691 if (self.liveness.isUnused(inst)) break :res MCValue.dead;3694 if (self.liveness.isUnused(inst)) break :res MCValue.dead;
3692 return self.fail("TODO implement airAggregateInit for {}", .{self.target.cpu.arch});3695 return self.fail("TODO implement airAggregateInit for {}", .{self.target.cpu.arch});
src/arch/arm/CodeGen.zig+8-5
...@@ -3144,7 +3144,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3144,7 +3144,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3144 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3144 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3145 const callee = pl_op.operand;3145 const callee = pl_op.operand;
3146 const extra = self.air.extraData(Air.Call, pl_op.payload);3146 const extra = self.air.extraData(Air.Call, pl_op.payload);
3147 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);3147 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3148 const ty = self.air.typeOf(callee);3148 const ty = self.air.typeOf(callee);
31493149
3150 const fn_ty = switch (ty.zigTypeTag()) {3150 const fn_ty = switch (ty.zigTypeTag()) {
...@@ -3650,7 +3650,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3650,7 +3650,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
3650 // TODO track the new register / stack allocation3650 // TODO track the new register / stack allocation
3651 }3651 }
36523652
3653 self.branch_stack.pop().deinit(self.gpa);3653 {
3654 var item = self.branch_stack.pop();
3655 item.deinit(self.gpa);
3656 }
36543657
3655 // We already took care of pl_op.operand earlier, so we're going3658 // We already took care of pl_op.operand earlier, so we're going
3656 // to pass .none here3659 // to pass .none here
...@@ -3951,9 +3954,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -3951,9 +3954,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
3951 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;3954 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
3952 const clobbers_len = @truncate(u31, extra.data.flags);3955 const clobbers_len = @truncate(u31, extra.data.flags);
3953 var extra_i: usize = extra.end;3956 var extra_i: usize = extra.end;
3954 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);3957 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
3955 extra_i += outputs.len;3958 extra_i += outputs.len;
3956 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);3959 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
3957 extra_i += inputs.len;3960 extra_i += inputs.len;
39583961
3959 const dead = !is_volatile and self.liveness.isUnused(inst);3962 const dead = !is_volatile and self.liveness.isUnused(inst);
...@@ -4735,7 +4738,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -4735,7 +4738,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
4735 const vector_ty = self.air.typeOfIndex(inst);4738 const vector_ty = self.air.typeOfIndex(inst);
4736 const len = vector_ty.vectorLen();4739 const len = vector_ty.vectorLen();
4737 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;4740 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4738 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);4741 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
4739 const result: MCValue = res: {4742 const result: MCValue = res: {
4740 if (self.liveness.isUnused(inst)) break :res MCValue.dead;4743 if (self.liveness.isUnused(inst)) break :res MCValue.dead;
4741 return self.fail("TODO implement airAggregateInit for arm", .{});4744 return self.fail("TODO implement airAggregateInit for arm", .{});
src/arch/arm/Emit.zig+18-7
...@@ -2,6 +2,7 @@...@@ -2,6 +2,7 @@
2//! machine code2//! machine code
33
4const Emit = @This();4const Emit = @This();
5const builtin = @import("builtin");
5const std = @import("std");6const std = @import("std");
6const math = std.math;7const math = std.math;
7const Mir = @import("Mir.zig");8const Mir = @import("Mir.zig");
...@@ -622,12 +623,17 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -622,12 +623,17 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void {
622 } else return emit.fail("TODO mirLoadStack larger offsets", .{});623 } else return emit.fail("TODO mirLoadStack larger offsets", .{});
623624
624 const ldr = switch (tag) {625 const ldr = switch (tag) {
625 .ldr_stack_argument => Instruction.ldr,626 .ldr_stack_argument => &Instruction.ldr,
626 .ldrb_stack_argument => Instruction.ldrb,627 .ldrb_stack_argument => &Instruction.ldrb,
627 else => unreachable,628 else => unreachable,
628 };629 };
629630
630 try emit.writeInstruction(ldr(631 const ldr_workaround = switch (builtin.zig_backend) {
632 .stage1 => ldr.*,
633 else => ldr,
634 };
635
636 try emit.writeInstruction(ldr_workaround(
631 cond,637 cond,
632 r_stack_offset.rt,638 r_stack_offset.rt,
633 .fp,639 .fp,
...@@ -643,13 +649,18 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -643,13 +649,18 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void {
643 } else return emit.fail("TODO mirLoadStack larger offsets", .{});649 } else return emit.fail("TODO mirLoadStack larger offsets", .{});
644650
645 const ldr = switch (tag) {651 const ldr = switch (tag) {
646 .ldrh_stack_argument => Instruction.ldrh,652 .ldrh_stack_argument => &Instruction.ldrh,
647 .ldrsb_stack_argument => Instruction.ldrsb,653 .ldrsb_stack_argument => &Instruction.ldrsb,
648 .ldrsh_stack_argument => Instruction.ldrsh,654 .ldrsh_stack_argument => &Instruction.ldrsh,
649 else => unreachable,655 else => unreachable,
650 };656 };
651657
652 try emit.writeInstruction(ldr(658 const ldr_workaround = switch (builtin.zig_backend) {
659 .stage1 => ldr.*,
660 else => ldr,
661 };
662
663 try emit.writeInstruction(ldr_workaround(
653 cond,664 cond,
654 r_stack_offset.rt,665 r_stack_offset.rt,
655 .fp,666 .fp,
src/arch/riscv64/CodeGen.zig+4-4
...@@ -1640,7 +1640,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -1640,7 +1640,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
1640 const fn_ty = self.air.typeOf(pl_op.operand);1640 const fn_ty = self.air.typeOf(pl_op.operand);
1641 const callee = pl_op.operand;1641 const callee = pl_op.operand;
1642 const extra = self.air.extraData(Air.Call, pl_op.payload);1642 const extra = self.air.extraData(Air.Call, pl_op.payload);
1643 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);1643 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
16441644
1645 var info = try self.resolveCallingConventionValues(fn_ty);1645 var info = try self.resolveCallingConventionValues(fn_ty);
1646 defer info.deinit(self);1646 defer info.deinit(self);
...@@ -2075,9 +2075,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -2075,9 +2075,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
2075 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;2075 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
2076 const clobbers_len = @truncate(u31, extra.data.flags);2076 const clobbers_len = @truncate(u31, extra.data.flags);
2077 var extra_i: usize = extra.end;2077 var extra_i: usize = extra.end;
2078 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);2078 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
2079 extra_i += outputs.len;2079 extra_i += outputs.len;
2080 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);2080 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
2081 extra_i += inputs.len;2081 extra_i += inputs.len;
20822082
2083 const dead = !is_volatile and self.liveness.isUnused(inst);2083 const dead = !is_volatile and self.liveness.isUnused(inst);
...@@ -2413,7 +2413,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -2413,7 +2413,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
2413 const vector_ty = self.air.typeOfIndex(inst);2413 const vector_ty = self.air.typeOfIndex(inst);
2414 const len = vector_ty.vectorLen();2414 const len = vector_ty.vectorLen();
2415 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2415 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2416 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);2416 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
2417 const result: MCValue = res: {2417 const result: MCValue = res: {
2418 if (self.liveness.isUnused(inst)) break :res MCValue.dead;2418 if (self.liveness.isUnused(inst)) break :res MCValue.dead;
2419 return self.fail("TODO implement airAggregateInit for riscv64", .{});2419 return self.fail("TODO implement airAggregateInit for riscv64", .{});
src/arch/wasm/CodeGen.zig+2-2
...@@ -2425,7 +2425,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2425,7 +2425,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2425 var highest_maybe: ?i32 = null;2425 var highest_maybe: ?i32 = null;
2426 while (case_i < switch_br.data.cases_len) : (case_i += 1) {2426 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
2427 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);2427 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
2428 const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);2428 const items = @ptrCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
2429 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];2429 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
2430 extra_index = case.end + items.len + case_body.len;2430 extra_index = case.end + items.len + case_body.len;
2431 const values = try self.gpa.alloc(CaseValue, items.len);2431 const values = try self.gpa.alloc(CaseValue, items.len);
...@@ -3328,7 +3328,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3328,7 +3328,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3328 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3328 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3329 const result_ty = self.air.typeOfIndex(inst);3329 const result_ty = self.air.typeOfIndex(inst);
3330 const len = @intCast(usize, result_ty.arrayLen());3330 const len = @intCast(usize, result_ty.arrayLen());
3331 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);3331 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
33323332
3333 switch (result_ty.zigTypeTag()) {3333 switch (result_ty.zigTypeTag()) {
3334 .Vector => return self.fail("TODO: Wasm backend: implement airAggregateInit for vectors", .{}),3334 .Vector => return self.fail("TODO: Wasm backend: implement airAggregateInit for vectors", .{}),
src/arch/x86_64/CodeGen.zig+14-8
...@@ -3501,7 +3501,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3501,7 +3501,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3501 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3501 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3502 const callee = pl_op.operand;3502 const callee = pl_op.operand;
3503 const extra = self.air.extraData(Air.Call, pl_op.payload);3503 const extra = self.air.extraData(Air.Call, pl_op.payload);
3504 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);3504 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3505 const ty = self.air.typeOf(callee);3505 const ty = self.air.typeOf(callee);
35063506
3507 const fn_ty = switch (ty.zigTypeTag()) {3507 const fn_ty = switch (ty.zigTypeTag()) {
...@@ -3684,7 +3684,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3684,7 +3684,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3684 .ops = (Mir.Ops{3684 .ops = (Mir.Ops{
3685 .flags = 0b01,3685 .flags = 0b01,
3686 }).encode(),3686 }).encode(),
3687 .data = .{ .imm = @bitCast(i32, @intCast(u32, fn_got_addr)) },3687 .data = .{ .imm = @intCast(u32, fn_got_addr) },
3688 });3688 });
3689 } else return self.fail("TODO implement calling extern fn on plan9", .{});3689 } else return self.fail("TODO implement calling extern fn on plan9", .{});
3690 } else {3690 } else {
...@@ -4220,7 +4220,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4220,7 +4220,10 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4220 // TODO track the new register / stack allocation4220 // TODO track the new register / stack allocation
4221 }4221 }
42224222
4223 self.branch_stack.pop().deinit(self.gpa);4223 {
4224 var item = self.branch_stack.pop();
4225 item.deinit(self.gpa);
4226 }
42244227
4225 // We already took care of pl_op.operand earlier, so we're going4228 // We already took care of pl_op.operand earlier, so we're going
4226 // to pass .none here4229 // to pass .none here
...@@ -4562,7 +4565,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {...@@ -4562,7 +4565,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
45624565
4563 while (case_i < switch_br.data.cases_len) : (case_i += 1) {4566 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
4564 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);4567 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
4565 const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);4568 const items = @ptrCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
4566 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];4569 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
4567 extra_index = case.end + items.len + case_body.len;4570 extra_index = case.end + items.len + case_body.len;
45684571
...@@ -4615,7 +4618,10 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {...@@ -4615,7 +4618,10 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
4615 if (switch_br.data.else_body_len > 0) {4618 if (switch_br.data.else_body_len > 0) {
4616 const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];4619 const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];
4617 try self.branch_stack.append(.{});4620 try self.branch_stack.append(.{});
4618 defer self.branch_stack.pop().deinit(self.gpa);4621 defer {
4622 var item = self.branch_stack.pop();
4623 item.deinit(self.gpa);
4624 }
46194625
4620 const else_deaths = liveness.deaths.len - 1;4626 const else_deaths = liveness.deaths.len - 1;
4621 try self.ensureProcessDeathCapacity(liveness.deaths[else_deaths].len);4627 try self.ensureProcessDeathCapacity(liveness.deaths[else_deaths].len);
...@@ -4705,9 +4711,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -4705,9 +4711,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
4705 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;4711 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
4706 const clobbers_len = @truncate(u31, extra.data.flags);4712 const clobbers_len = @truncate(u31, extra.data.flags);
4707 var extra_i: usize = extra.end;4713 var extra_i: usize = extra.end;
4708 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);4714 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
4709 extra_i += outputs.len;4715 extra_i += outputs.len;
4710 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);4716 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
4711 extra_i += inputs.len;4717 extra_i += inputs.len;
47124718
4713 const dead = !is_volatile and self.liveness.isUnused(inst);4719 const dead = !is_volatile and self.liveness.isUnused(inst);
...@@ -5975,7 +5981,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -5975,7 +5981,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
5975 const result_ty = self.air.typeOfIndex(inst);5981 const result_ty = self.air.typeOfIndex(inst);
5976 const len = @intCast(usize, result_ty.arrayLen());5982 const len = @intCast(usize, result_ty.arrayLen());
5977 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5983 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5978 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);5984 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
5979 const abi_size = @intCast(u32, result_ty.abiSize(self.target.*));5985 const abi_size = @intCast(u32, result_ty.abiSize(self.target.*));
5980 const abi_align = result_ty.abiAlignment(self.target.*);5986 const abi_align = result_ty.abiAlignment(self.target.*);
5981 const result: MCValue = res: {5987 const result: MCValue = res: {
src/codegen/c.zig+8-9
...@@ -220,6 +220,9 @@ fn formatIdent(...@@ -220,6 +220,9 @@ fn formatIdent(
220}220}
221221
222pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {222pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {
223 if (builtin.zig_backend != .stage1) {
224 @panic("TODO");
225 }
223 return .{ .data = ident };226 return .{ .data = ident };
224}227}
225228
...@@ -2310,7 +2313,6 @@ fn airWrapOp(...@@ -2310,7 +2313,6 @@ fn airWrapOp(
2310 const val = -1 * std.math.pow(i64, 2, @intCast(i64, bits - 1));2313 const val = -1 * std.math.pow(i64, 2, @intCast(i64, bits - 1));
2311 break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) {2314 break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) {
2312 error.NoSpaceLeft => unreachable,2315 error.NoSpaceLeft => unreachable,
2313 else => |e| return e,
2314 };2316 };
2315 },2317 },
2316 },2318 },
...@@ -2336,7 +2338,6 @@ fn airWrapOp(...@@ -2336,7 +2338,6 @@ fn airWrapOp(
2336 const val = std.math.pow(u64, 2, pow_bits) - 1;2338 const val = std.math.pow(u64, 2, pow_bits) - 1;
2337 break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) {2339 break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) {
2338 error.NoSpaceLeft => unreachable,2340 error.NoSpaceLeft => unreachable,
2339 else => |e| return e,
2340 };2341 };
2341 },2342 },
2342 };2343 };
...@@ -2418,7 +2419,6 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {...@@ -2418,7 +2419,6 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
2418 const val = -1 * std.math.pow(i65, 2, @intCast(i65, bits - 1));2419 const val = -1 * std.math.pow(i65, 2, @intCast(i65, bits - 1));
2419 break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) {2420 break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) {
2420 error.NoSpaceLeft => unreachable,2421 error.NoSpaceLeft => unreachable,
2421 else => |e| return e,
2422 };2422 };
2423 },2423 },
2424 },2424 },
...@@ -2444,7 +2444,6 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {...@@ -2444,7 +2444,6 @@ fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue {
2444 const val = std.math.pow(u65, 2, pow_bits) - 1;2444 const val = std.math.pow(u65, 2, pow_bits) - 1;
2445 break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) {2445 break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) {
2446 error.NoSpaceLeft => unreachable,2446 error.NoSpaceLeft => unreachable,
2447 else => |e| return e,
2448 };2447 };
2449 },2448 },
2450 };2449 };
...@@ -2702,7 +2701,7 @@ fn airCall(...@@ -2702,7 +2701,7 @@ fn airCall(
2702 }2701 }
2703 const pl_op = f.air.instructions.items(.data)[inst].pl_op;2702 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
2704 const extra = f.air.extraData(Air.Call, pl_op.payload);2703 const extra = f.air.extraData(Air.Call, pl_op.payload);
2705 const args = @bitCast([]const Air.Inst.Ref, f.air.extra[extra.end..][0..extra.data.args_len]);2704 const args = @ptrCast([]const Air.Inst.Ref, f.air.extra[extra.end..][0..extra.data.args_len]);
2706 const callee_ty = f.air.typeOf(pl_op.operand);2705 const callee_ty = f.air.typeOf(pl_op.operand);
2707 const fn_ty = switch (callee_ty.zigTypeTag()) {2706 const fn_ty = switch (callee_ty.zigTypeTag()) {
2708 .Fn => callee_ty,2707 .Fn => callee_ty,
...@@ -2959,7 +2958,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2959,7 +2958,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
2959 var case_i: u32 = 0;2958 var case_i: u32 = 0;
2960 while (case_i < switch_br.data.cases_len) : (case_i += 1) {2959 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
2961 const case = f.air.extraData(Air.SwitchBr.Case, extra_index);2960 const case = f.air.extraData(Air.SwitchBr.Case, extra_index);
2962 const items = @bitCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]);2961 const items = @ptrCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]);
2963 const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len];2962 const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len];
2964 extra_index = case.end + case.data.items_len + case_body.len;2963 extra_index = case.end + case.data.items_len + case_body.len;
29652964
...@@ -2990,9 +2989,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2990,9 +2989,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
2990 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;2989 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
2991 const clobbers_len = @truncate(u31, extra.data.flags);2990 const clobbers_len = @truncate(u31, extra.data.flags);
2992 var extra_i: usize = extra.end;2991 var extra_i: usize = extra.end;
2993 const outputs = @bitCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.outputs_len]);2992 const outputs = @ptrCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.outputs_len]);
2994 extra_i += outputs.len;2993 extra_i += outputs.len;
2995 const inputs = @bitCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.inputs_len]);2994 const inputs = @ptrCast([]const Air.Inst.Ref, f.air.extra[extra_i..][0..extra.data.inputs_len]);
2996 extra_i += inputs.len;2995 extra_i += inputs.len;
29972996
2998 if (!is_volatile and f.liveness.isUnused(inst)) return CValue.none;2997 if (!is_volatile and f.liveness.isUnused(inst)) return CValue.none;
...@@ -3860,7 +3859,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3860,7 +3859,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
3860 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3859 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3861 const vector_ty = f.air.getRefType(ty_pl.ty);3860 const vector_ty = f.air.getRefType(ty_pl.ty);
3862 const len = vector_ty.vectorLen();3861 const len = vector_ty.vectorLen();
3863 const elements = @bitCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);3862 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
38643863
3865 const writer = f.object.writer();3864 const writer = f.object.writer();
3866 const local = try f.allocLocal(inst_ty, .Const);3865 const local = try f.allocLocal(inst_ty, .Const);
src/codegen/llvm.zig+5-5
...@@ -3657,7 +3657,7 @@ pub const FuncGen = struct {...@@ -3657,7 +3657,7 @@ pub const FuncGen = struct {
3657 fn airCall(self: *FuncGen, inst: Air.Inst.Index, attr: llvm.CallAttr) !?*const llvm.Value {3657 fn airCall(self: *FuncGen, inst: Air.Inst.Index, attr: llvm.CallAttr) !?*const llvm.Value {
3658 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3658 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3659 const extra = self.air.extraData(Air.Call, pl_op.payload);3659 const extra = self.air.extraData(Air.Call, pl_op.payload);
3660 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);3660 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3661 const callee_ty = self.air.typeOf(pl_op.operand);3661 const callee_ty = self.air.typeOf(pl_op.operand);
3662 const zig_fn_ty = switch (callee_ty.zigTypeTag()) {3662 const zig_fn_ty = switch (callee_ty.zigTypeTag()) {
3663 .Fn => callee_ty,3663 .Fn => callee_ty,
...@@ -4037,7 +4037,7 @@ pub const FuncGen = struct {...@@ -4037,7 +4037,7 @@ pub const FuncGen = struct {
40374037
4038 while (case_i < switch_br.data.cases_len) : (case_i += 1) {4038 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
4039 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);4039 const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
4040 const items = @bitCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);4040 const items = @ptrCast([]const Air.Inst.Ref, self.air.extra[case.end..][0..case.data.items_len]);
4041 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];4041 const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
4042 extra_index = case.end + case.data.items_len + case_body.len;4042 extra_index = case.end + case.data.items_len + case_body.len;
40434043
...@@ -4538,9 +4538,9 @@ pub const FuncGen = struct {...@@ -4538,9 +4538,9 @@ pub const FuncGen = struct {
45384538
4539 if (!is_volatile and self.liveness.isUnused(inst)) return null;4539 if (!is_volatile and self.liveness.isUnused(inst)) return null;
45404540
4541 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);4541 const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
4542 extra_i += outputs.len;4542 extra_i += outputs.len;
4543 const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);4543 const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
4544 extra_i += inputs.len;4544 extra_i += inputs.len;
45454545
4546 if (outputs.len > 1) {4546 if (outputs.len > 1) {
...@@ -6660,7 +6660,7 @@ pub const FuncGen = struct {...@@ -6660,7 +6660,7 @@ pub const FuncGen = struct {
6660 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6660 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6661 const result_ty = self.air.typeOfIndex(inst);6661 const result_ty = self.air.typeOfIndex(inst);
6662 const len = @intCast(usize, result_ty.arrayLen());6662 const len = @intCast(usize, result_ty.arrayLen());
6663 const elements = @bitCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);6663 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
6664 const llvm_result_ty = try self.dg.llvmType(result_ty);6664 const llvm_result_ty = try self.dg.llvmType(result_ty);
6665 const target = self.dg.module.getTarget();6665 const target = self.dg.module.getTarget();
66666666
src/link.zig+6-1
...@@ -649,6 +649,11 @@ pub const File = struct {...@@ -649,6 +649,11 @@ pub const File = struct {
649 }649 }
650 }650 }
651651
652 pub const UpdateDeclExportsError = error{
653 OutOfMemory,
654 AnalysisFail,
655 };
656
652 /// May be called before or after updateDecl, but must be called after657 /// May be called before or after updateDecl, but must be called after
653 /// allocateDeclIndexes for any given Decl.658 /// allocateDeclIndexes for any given Decl.
654 pub fn updateDeclExports(659 pub fn updateDeclExports(
...@@ -656,7 +661,7 @@ pub const File = struct {...@@ -656,7 +661,7 @@ pub const File = struct {
656 module: *Module,661 module: *Module,
657 decl: *Module.Decl,662 decl: *Module.Decl,
658 exports: []const *Module.Export,663 exports: []const *Module.Export,
659 ) !void {664 ) UpdateDeclExportsError!void {
660 log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });665 log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });
661 assert(decl.has_tv);666 assert(decl.has_tv);
662 switch (base.tag) {667 switch (base.tag) {
src/link/C.zig+3-2
...@@ -89,8 +89,9 @@ pub fn deinit(self: *C) void {...@@ -89,8 +89,9 @@ pub fn deinit(self: *C) void {
8989
90pub fn freeDecl(self: *C, decl: *Module.Decl) void {90pub fn freeDecl(self: *C, decl: *Module.Decl) void {
91 const gpa = self.base.allocator;91 const gpa = self.base.allocator;
92 if (self.decl_table.fetchSwapRemove(decl)) |*kv| {92 if (self.decl_table.fetchSwapRemove(decl)) |kv| {
93 kv.value.deinit(gpa);93 var decl_block = kv.value;
94 decl_block.deinit(gpa);
94 }95 }
95}96}
9697
src/link/Elf.zig+1-1
...@@ -2482,7 +2482,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl...@@ -2482,7 +2482,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
2482 try self.atom_by_index_table.putNoClobber(self.base.allocator, atom.local_sym_index, atom);2482 try self.atom_by_index_table.putNoClobber(self.base.allocator, atom.local_sym_index, atom);
24832483
2484 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{2484 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{
2485 .none = .{},2485 .none = {},
2486 }, .{2486 }, .{
2487 .parent_atom_index = atom.local_sym_index,2487 .parent_atom_index = atom.local_sym_index,
2488 });2488 });
src/link/MachO/Object.zig-1
...@@ -625,7 +625,6 @@ pub fn parseDataInCode(self: *Object, allocator: Allocator) !void {...@@ -625,7 +625,6 @@ pub fn parseDataInCode(self: *Object, allocator: Allocator) !void {
625 while (true) {625 while (true) {
626 const dice = reader.readStruct(macho.data_in_code_entry) catch |err| switch (err) {626 const dice = reader.readStruct(macho.data_in_code_entry) catch |err| switch (err) {
627 error.EndOfStream => break,627 error.EndOfStream => break,
628 else => |e| return e,
629 };628 };
630 try self.data_in_code_entries.append(allocator, dice);629 try self.data_in_code_entries.append(allocator, dice);
631 }630 }
src/link/MachO/fat.zig-1
...@@ -40,7 +40,6 @@ pub fn getLibraryOffset(reader: anytype, target: std.Target) !u64 {...@@ -40,7 +40,6 @@ pub fn getLibraryOffset(reader: anytype, target: std.Target) !u64 {
40 // fine because we can keep looking for one that might match.40 // fine because we can keep looking for one that might match.
41 const lib_arch = decodeArch(fat_arch.cputype, false) catch |err| switch (err) {41 const lib_arch = decodeArch(fat_arch.cputype, false) catch |err| switch (err) {
42 error.UnsupportedCpuArchitecture => continue,42 error.UnsupportedCpuArchitecture => continue,
43 else => |e| return e,
44 };43 };
45 if (lib_arch == target.cpu.arch) {44 if (lib_arch == target.cpu.arch) {
46 // We have found a matching architecture!45 // We have found a matching architecture!
src/link/Plan9.zig+1-1
...@@ -307,7 +307,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {...@@ -307,7 +307,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {
307 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{307 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
308 .ty = decl.ty,308 .ty = decl.ty,
309 .val = decl_val,309 .val = decl_val,
310 }, &code_buffer, .{ .none = .{} }, .{310 }, &code_buffer, .{ .none = {} }, .{
311 .parent_atom_index = @intCast(u32, sym_index),311 .parent_atom_index = @intCast(u32, sym_index),
312 });312 });
313 const code = switch (res) {313 const code = switch (res) {
src/link/Wasm.zig+16-10
...@@ -2551,7 +2551,8 @@ fn emitSymbolTable(self: *Wasm, file: fs.File, arena: Allocator, symbol_table: *...@@ -2551,7 +2551,8 @@ fn emitSymbolTable(self: *Wasm, file: fs.File, arena: Allocator, symbol_table: *
2551 .iov_base = payload.items.ptr,2551 .iov_base = payload.items.ptr,
2552 .iov_len = payload.items.len,2552 .iov_len = payload.items.len,
2553 };2553 };
2554 try file.writevAll(&.{iovec});2554 var iovecs = [_]std.os.iovec_const{iovec};
2555 try file.writevAll(&iovecs);
2555}2556}
25562557
2557fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {2558fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {
...@@ -2576,7 +2577,8 @@ fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {...@@ -2576,7 +2577,8 @@ fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {
2576 .iov_base = payload.items.ptr,2577 .iov_base = payload.items.ptr,
2577 .iov_len = payload.items.len,2578 .iov_len = payload.items.len,
2578 };2579 };
2579 try file.writevAll(&.{iovec});2580 var iovecs = [_]std.os.iovec_const{iovec};
2581 try file.writevAll(&iovecs);
2580}2582}
25812583
2582fn getULEB128Size(uint_value: anytype) u32 {2584fn getULEB128Size(uint_value: anytype) u32 {
...@@ -2635,12 +2637,14 @@ fn emitCodeRelocations(...@@ -2635,12 +2637,14 @@ fn emitCodeRelocations(
2635 var buf: [5]u8 = undefined;2637 var buf: [5]u8 = undefined;
2636 leb.writeUnsignedFixed(5, &buf, count);2638 leb.writeUnsignedFixed(5, &buf, count);
2637 try payload.insertSlice(reloc_start, &buf);2639 try payload.insertSlice(reloc_start, &buf);
2638 const iovec: std.os.iovec_const = .{2640 var iovecs = [_]std.os.iovec_const{
2639 .iov_base = payload.items.ptr,2641 .{
2640 .iov_len = payload.items.len,2642 .iov_base = payload.items.ptr,
2643 .iov_len = payload.items.len,
2644 },
2641 };2645 };
2642 const header_offset = try reserveCustomSectionHeader(file);2646 const header_offset = try reserveCustomSectionHeader(file);
2643 try file.writevAll(&.{iovec});2647 try file.writevAll(&iovecs);
2644 const size = @intCast(u32, payload.items.len);2648 const size = @intCast(u32, payload.items.len);
2645 try writeCustomSectionHeader(file, header_offset, size);2649 try writeCustomSectionHeader(file, header_offset, size);
2646}2650}
...@@ -2694,12 +2698,14 @@ fn emitDataRelocations(...@@ -2694,12 +2698,14 @@ fn emitDataRelocations(
2694 var buf: [5]u8 = undefined;2698 var buf: [5]u8 = undefined;
2695 leb.writeUnsignedFixed(5, &buf, count);2699 leb.writeUnsignedFixed(5, &buf, count);
2696 try payload.insertSlice(reloc_start, &buf);2700 try payload.insertSlice(reloc_start, &buf);
2697 const iovec: std.os.iovec_const = .{2701 var iovecs = [_]std.os.iovec_const{
2698 .iov_base = payload.items.ptr,2702 .{
2699 .iov_len = payload.items.len,2703 .iov_base = payload.items.ptr,
2704 .iov_len = payload.items.len,
2705 },
2700 };2706 };
2701 const header_offset = try reserveCustomSectionHeader(file);2707 const header_offset = try reserveCustomSectionHeader(file);
2702 try file.writevAll(&.{iovec});2708 try file.writevAll(&iovecs);
2703 const size = @intCast(u32, payload.items.len);2709 const size = @intCast(u32, payload.items.len);
2704 try writeCustomSectionHeader(file, header_offset, size);2710 try writeCustomSectionHeader(file, header_offset, size);
2705}2711}
src/print_air.zig+5-5
...@@ -328,7 +328,7 @@ const Writer = struct {...@@ -328,7 +328,7 @@ const Writer = struct {
328 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;328 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
329 const vector_ty = w.air.getRefType(ty_pl.ty);329 const vector_ty = w.air.getRefType(ty_pl.ty);
330 const len = @intCast(usize, vector_ty.arrayLen());330 const len = @intCast(usize, vector_ty.arrayLen());
331 const elements = @bitCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);331 const elements = @ptrCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);
332332
333 try s.print("{}, [", .{vector_ty.fmtDebug()});333 try s.print("{}, [", .{vector_ty.fmtDebug()});
334 for (elements) |elem, i| {334 for (elements) |elem, i| {
...@@ -533,9 +533,9 @@ const Writer = struct {...@@ -533,9 +533,9 @@ const Writer = struct {
533 try s.writeAll(", volatile");533 try s.writeAll(", volatile");
534 }534 }
535535
536 const outputs = @bitCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.outputs_len]);536 const outputs = @ptrCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.outputs_len]);
537 extra_i += outputs.len;537 extra_i += outputs.len;
538 const inputs = @bitCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.inputs_len]);538 const inputs = @ptrCast([]const Air.Inst.Ref, w.air.extra[extra_i..][0..extra.data.inputs_len]);
539 extra_i += inputs.len;539 extra_i += inputs.len;
540540
541 for (outputs) |output| {541 for (outputs) |output| {
...@@ -604,7 +604,7 @@ const Writer = struct {...@@ -604,7 +604,7 @@ const Writer = struct {
604 fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {604 fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
605 const pl_op = w.air.instructions.items(.data)[inst].pl_op;605 const pl_op = w.air.instructions.items(.data)[inst].pl_op;
606 const extra = w.air.extraData(Air.Call, pl_op.payload);606 const extra = w.air.extraData(Air.Call, pl_op.payload);
607 const args = @bitCast([]const Air.Inst.Ref, w.air.extra[extra.end..][0..extra.data.args_len]);607 const args = @ptrCast([]const Air.Inst.Ref, w.air.extra[extra.end..][0..extra.data.args_len]);
608 try w.writeOperand(s, inst, 0, pl_op.operand);608 try w.writeOperand(s, inst, 0, pl_op.operand);
609 try s.writeAll(", [");609 try s.writeAll(", [");
610 for (args) |arg, i| {610 for (args) |arg, i| {
...@@ -674,7 +674,7 @@ const Writer = struct {...@@ -674,7 +674,7 @@ const Writer = struct {
674674
675 while (case_i < switch_br.data.cases_len) : (case_i += 1) {675 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
676 const case = w.air.extraData(Air.SwitchBr.Case, extra_index);676 const case = w.air.extraData(Air.SwitchBr.Case, extra_index);
677 const items = @bitCast([]const Air.Inst.Ref, w.air.extra[case.end..][0..case.data.items_len]);677 const items = @ptrCast([]const Air.Inst.Ref, w.air.extra[case.end..][0..case.data.items_len]);
678 const case_body = w.air.extra[case.end + items.len ..][0..case.data.body_len];678 const case_body = w.air.extra[case.end + items.len ..][0..case.data.body_len];
679 extra_index = case.end + case.data.items_len + case_body.len;679 extra_index = case.end + case.data.items_len + case_body.len;
680680
src/stage1/ir.cpp+6
...@@ -23052,6 +23052,12 @@ static Stage1AirInst *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, Stage1ZirI...@@ -23052,6 +23052,12 @@ static Stage1AirInst *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, Stage1ZirI
23052 if (type_is_invalid(src_type))23052 if (type_is_invalid(src_type))
23053 return ira->codegen->invalid_inst_gen;23053 return ira->codegen->invalid_inst_gen;
2305423054
23055 // This logic is not quite right; this is just to get stage1 to accept valid code
23056 // we use in the self-hosted compiler.
23057 if (is_slice(dest_type) && is_slice(src_type)) {
23058 return ir_analyze_bit_cast(ira, instruction->base.scope, instruction->base.source_node, ptr, dest_type);
23059 }
23060
23055 bool keep_bigger_alignment = true;23061 bool keep_bigger_alignment = true;
23056 return ir_analyze_ptr_cast(ira, instruction->base.scope, instruction->base.source_node, ptr,23062 return ir_analyze_ptr_cast(ira, instruction->base.scope, instruction->base.source_node, ptr,
23057 instruction->ptr->source_node, dest_type, dest_type_value->source_node,23063 instruction->ptr->source_node, dest_type, dest_type_value->source_node,
src/type.zig+1-1
...@@ -1451,7 +1451,7 @@ pub const Type = extern union {...@@ -1451,7 +1451,7 @@ pub const Type = extern union {
1451 var duped_names = Module.ErrorSet.NameMap{};1451 var duped_names = Module.ErrorSet.NameMap{};
1452 try duped_names.ensureTotalCapacity(allocator, names.len);1452 try duped_names.ensureTotalCapacity(allocator, names.len);
1453 for (names) |name| {1453 for (names) |name| {
1454 duped_names.putAssumeCapacityNoClobber(name, .{});1454 duped_names.putAssumeCapacityNoClobber(name, {});
1455 }1455 }
1456 return Tag.error_set_merged.create(allocator, duped_names);1456 return Tag.error_set_merged.create(allocator, duped_names);
1457 },1457 },
test/behavior/ptrcast.zig+16
...@@ -217,3 +217,19 @@ test "implicit optional pointer to optional anyopaque pointer" {...@@ -217,3 +217,19 @@ test "implicit optional pointer to optional anyopaque pointer" {
217 var z = @ptrCast(*[4]u8, y);217 var z = @ptrCast(*[4]u8, y);
218 try expect(std.mem.eql(u8, z, "aoeu"));218 try expect(std.mem.eql(u8, z, "aoeu"));
219}219}
220
221test "@ptrCast slice to slice" {
222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
224
225 const S = struct {
226 fn foo(slice: []u32) []i32 {
227 return @ptrCast([]i32, slice);
228 }
229 };
230 var buf: [4]u32 = .{ 0, 0, 0, 0 };
231 const alias = S.foo(&buf);
232 alias[1] = 42;
233 try expect(buf[1] == 42);
234 try expect(alias.len == 4);
235}