authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-02 15:53:59-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-11-02 15:53:59-04:00
loge50789f1cb13522a3bdace2a2359711163c3fd55
tree14154a31df2372e1dc99d40a613743912faeaf5e
parent57dbeb90affb81501d18210db0075620e40dfefb
parent37c104ade05487f24f4ed1fd7e3251a6fc2c804d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13389 from jacobly0/fix-only-c

cbe: enough fixes for `-Donly-c` to be able to produce an executable

18 files changed, 332 insertions(+), 184 deletions(-)

build.zig+5-5
......@@ -17,7 +17,7 @@ pub fn build(b: *Builder) !void {
1717 b.setPreferredReleaseMode(.ReleaseFast);
1818 const test_step = b.step("test", "Run all the tests");
1919 const mode = b.standardReleaseOptions();
20 const target = b.standardTargetOptions(.{});
20 var target = b.standardTargetOptions(.{});
2121 const single_threaded = b.option(bool, "single-threaded", "Build artifacts that run in single threaded mode");
2222 const use_zig_libcxx = b.option(bool, "use-zig-libcxx", "If libc++ is needed, use zig's bundled version, don't try to integrate with the system") orelse false;
2323
......@@ -141,6 +141,10 @@ pub fn build(b: *Builder) !void {
141141 break :blk 4;
142142 };
143143
144 if (only_c) {
145 target.ofmt = .c;
146 }
147
144148 const main_file: ?[]const u8 = mf: {
145149 if (!have_stage1) break :mf "src/main.zig";
146150 if (use_zig0) break :mf null;
......@@ -172,10 +176,6 @@ pub fn build(b: *Builder) !void {
172176 test_cases.want_lto = false;
173177 }
174178
175 if (only_c) {
176 exe.ofmt = .c;
177 }
178
179179 const exe_options = b.addOptions();
180180 exe.addOptions("build_options", exe_options);
181181
lib/include/zig.h+1-1
......@@ -19,7 +19,7 @@
1919#endif
2020
2121#if __STDC_VERSION__ >= 201112L
22#define zig_threadlocal thread_local
22#define zig_threadlocal _Thread_local
2323#elif defined(__GNUC__)
2424#define zig_threadlocal __thread
2525#elif _MSC_VER
lib/std/build.zig+1-2
......@@ -1622,7 +1622,6 @@ pub const LibExeObjStep = struct {
16221622 use_stage1: ?bool = null,
16231623 use_llvm: ?bool = null,
16241624 use_lld: ?bool = null,
1625 ofmt: ?std.Target.ObjectFormat = null,
16261625
16271626 output_path_source: GeneratedFile,
16281627 output_lib_path_source: GeneratedFile,
......@@ -2490,7 +2489,7 @@ pub const LibExeObjStep = struct {
24902489 }
24912490 }
24922491
2493 if (self.ofmt) |ofmt| {
2492 if (self.target.ofmt) |ofmt| {
24942493 try zig_args.append(try std.fmt.allocPrint(builder.allocator, "-ofmt={s}", .{@tagName(ofmt)}));
24952494 }
24962495
lib/std/crypto/blake3.zig+4-1
......@@ -200,7 +200,10 @@ const CompressGeneric = struct {
200200 }
201201};
202202
203const compress = if (builtin.cpu.arch == .x86_64) CompressVectorized.compress else CompressGeneric.compress;
203const compress = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c)
204 CompressVectorized.compress
205else
206 CompressGeneric.compress;
204207
205208fn first8Words(words: [16]u32) [8]u32 {
206209 return @ptrCast(*const [8]u32, &words).*;
lib/std/crypto/gimli.zig+1-1
......@@ -152,7 +152,7 @@ pub const State = struct {
152152 self.endianSwap();
153153 }
154154
155 pub const permute = if (builtin.cpu.arch == .x86_64) impl: {
155 pub const permute = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c) impl: {
156156 break :impl permute_vectorized;
157157 } else if (builtin.mode == .ReleaseSmall) impl: {
158158 break :impl permute_small;
lib/std/multi_array_list.zig+9-3
......@@ -436,9 +436,15 @@ pub fn MultiArrayList(comptime S: type) type {
436436 }
437437
438438 fn capacityInBytes(capacity: usize) usize {
439 const sizes_vector: @Vector(sizes.bytes.len, usize) = sizes.bytes;
440 const capacity_vector = @splat(sizes.bytes.len, capacity);
441 return @reduce(.Add, capacity_vector * sizes_vector);
439 if (builtin.zig_backend == .stage2_c) {
440 var bytes: usize = 0;
441 for (sizes.bytes) |size| bytes += size * capacity;
442 return bytes;
443 } else {
444 const sizes_vector: @Vector(sizes.bytes.len, usize) = sizes.bytes;
445 const capacity_vector = @splat(sizes.bytes.len, capacity);
446 return @reduce(.Add, capacity_vector * sizes_vector);
447 }
442448 }
443449
444450 fn allocatedBytes(self: Self) []align(@alignOf(S)) u8 {
lib/std/target.zig+11-2
......@@ -1,4 +1,5 @@
11const std = @import("std.zig");
2const builtin = @import("builtin");
23const mem = std.mem;
34const Version = std.builtin.Version;
45
......@@ -719,7 +720,11 @@ pub const Target = struct {
719720
720721 /// Adds the specified feature set but not its dependencies.
721722 pub fn addFeatureSet(set: *Set, other_set: Set) void {
722 set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints);
723 if (builtin.zig_backend == .stage2_c) {
724 for (set.ints) |*int, i| int.* |= other_set.ints[i];
725 } else {
726 set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints);
727 }
723728 }
724729
725730 /// Removes the specified feature but not its dependents.
......@@ -731,7 +736,11 @@ pub const Target = struct {
731736
732737 /// Removes the specified feature but not its dependents.
733738 pub fn removeFeatureSet(set: *Set, other_set: Set) void {
734 set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints);
739 if (builtin.zig_backend == .stage2_c) {
740 for (set.ints) |*int, i| int.* &= ~other_set.ints[i];
741 } else {
742 set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints);
743 }
735744 }
736745
737746 pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void {
lib/std/zig/system/x86.zig+14-20
......@@ -528,26 +528,20 @@ const CpuidLeaf = packed struct {
528528};
529529
530530fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf {
531 // Workaround for https://github.com/ziglang/zig/issues/215
532 // Inline assembly in zig only supports one output,
533 // so we pass a pointer to the struct.
534 var cpuid_leaf: CpuidLeaf = undefined;
535
536531 // valid for both x86 and x86_64
537 asm volatile (
538 \\ cpuid
539 \\ movl %%eax, 0(%[leaf_ptr])
540 \\ movl %%ebx, 4(%[leaf_ptr])
541 \\ movl %%ecx, 8(%[leaf_ptr])
542 \\ movl %%edx, 12(%[leaf_ptr])
543 :
544 : [leaf_id] "{eax}" (leaf_id),
545 [subid] "{ecx}" (subid),
546 [leaf_ptr] "r" (&cpuid_leaf),
547 : "eax", "ebx", "ecx", "edx"
532 var eax: u32 = undefined;
533 var ebx: u32 = undefined;
534 var ecx: u32 = undefined;
535 var edx: u32 = undefined;
536 asm volatile ("cpuid"
537 : [_] "={eax}" (eax),
538 [_] "={ebx}" (ebx),
539 [_] "={ecx}" (ecx),
540 [_] "={edx}" (edx),
541 : [_] "{eax}" (leaf_id),
542 [_] "{ecx}" (subid),
548543 );
549
550 return cpuid_leaf;
544 return .{ .eax = eax, .ebx = ebx, .ecx = ecx, .edx = edx };
551545}
552546
553547// Read control register 0 (XCR0). Used to detect features such as AVX.
......@@ -555,8 +549,8 @@ fn getXCR0() u32 {
555549 return asm volatile (
556550 \\ xor %%ecx, %%ecx
557551 \\ xgetbv
558 : [ret] "={eax}" (-> u32),
552 : [_] "={eax}" (-> u32),
559553 :
560 : "eax", "edx", "ecx"
554 : "edx", "ecx"
561555 );
562556}
src/codegen/c.zig+283-140
......@@ -32,6 +32,8 @@ pub const CValue = union(enum) {
3232 constant: Air.Inst.Ref,
3333 /// Index into the parameters
3434 arg: usize,
35 /// Index into a tuple's fields
36 field: usize,
3537 /// By-value
3638 decl: Decl.Index,
3739 decl_ref: Decl.Index,
......@@ -79,7 +81,6 @@ const BuiltinInfo = enum {
7981 Bits,
8082};
8183
82/// TODO make this not cut off at 128 bytes
8384fn formatTypeAsCIdentifier(
8485 data: FormatTypeAsCIdentContext,
8586 comptime fmt: []const u8,
......@@ -1297,7 +1298,8 @@ pub const DeclGen = struct {
12971298 var fqn_buf = std.ArrayList(u8).init(dg.typedefs.allocator);
12981299 defer fqn_buf.deinit();
12991300
1300 const owner_decl = dg.module.declPtr(child_ty.getOwnerDecl());
1301 const owner_decl_index = child_ty.getOwnerDecl();
1302 const owner_decl = dg.module.declPtr(owner_decl_index);
13011303 try owner_decl.renderFullyQualifiedName(dg.module, fqn_buf.writer());
13021304
13031305 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
......@@ -1309,7 +1311,11 @@ pub const DeclGen = struct {
13091311 else => unreachable,
13101312 };
13111313 const name_begin = buffer.items.len + "typedef ".len + tag.len;
1312 try buffer.writer().print("typedef {s}zig_S_{} ", .{ tag, fmtIdent(fqn_buf.items) });
1314 try buffer.writer().print("typedef {s}zig_S_{}__{d} ", .{
1315 tag,
1316 fmtIdent(fqn_buf.items),
1317 @enumToInt(owner_decl_index),
1318 });
13131319 const name_end = buffer.items.len - " ".len;
13141320 try buffer.ensureUnusedCapacity((name_end - name_begin) + ";\n".len);
13151321 buffer.appendSliceAssumeCapacity(buffer.items[name_begin..name_end]);
......@@ -1378,26 +1384,17 @@ pub const DeclGen = struct {
13781384 try buffer.appendSlice("typedef struct {\n");
13791385 {
13801386 const fields = t.tupleFields();
1381 var empty = true;
1387 var field_id: usize = 0;
13821388 for (fields.types) |field_ty, i| {
1383 if (!field_ty.hasRuntimeBits()) continue;
1384 const val = fields.values[i];
1385 if (val.tag() != .unreachable_value) continue;
1386
1387 var field_name_buf: []const u8 = &.{};
1388 defer dg.typedefs.allocator.free(field_name_buf);
1389 const field_name = if (t.isTuple()) field_name: {
1390 field_name_buf = try std.fmt.allocPrint(dg.typedefs.allocator, "field_{d}", .{i});
1391 break :field_name field_name_buf;
1392 } else t.structFieldName(i);
1389 if (!field_ty.hasRuntimeBits() or fields.values[i].tag() != .unreachable_value) continue;
13931390
13941391 try buffer.append(' ');
1395 try dg.renderTypeAndName(buffer.writer(), field_ty, .{ .identifier = field_name }, .Mut, 0, .Complete);
1392 try dg.renderTypeAndName(buffer.writer(), field_ty, .{ .field = field_id }, .Mut, 0, .Complete);
13961393 try buffer.appendSlice(";\n");
13971394
1398 empty = false;
1395 field_id += 1;
13991396 }
1400 if (empty) try buffer.appendSlice(" char empty_tuple;\n");
1397 if (field_id == 0) try buffer.appendSlice(" char empty_tuple;\n");
14011398 }
14021399 const name_begin = buffer.items.len + "} ".len;
14031400 try buffer.writer().print("}} zig_T_{};\n", .{typeToCIdentifier(t, dg.module)});
......@@ -1751,12 +1748,38 @@ pub const DeclGen = struct {
17511748 },
17521749 .Struct, .Union => |tag| if (tag == .Struct and t.containerLayout() == .Packed)
17531750 try dg.renderType(w, t.castTag(.@"struct").?.data.backing_int_ty, kind)
1754 else if (kind == .Complete or t.isTupleOrAnonStruct()) {
1751 else if (t.isTupleOrAnonStruct()) {
1752 const ExpectedContents = struct { types: [8]Type, values: [8]Value };
1753 var stack align(@alignOf(ExpectedContents)) =
1754 std.heap.stackFallback(@sizeOf(ExpectedContents), dg.gpa);
1755 const allocator = stack.get();
1756
1757 var tuple_storage = std.MultiArrayList(struct { type: Type, value: Value }){};
1758 defer tuple_storage.deinit(allocator);
1759 try tuple_storage.ensureTotalCapacity(allocator, t.structFieldCount());
1760
1761 const fields = t.tupleFields();
1762 for (fields.values) |value, index|
1763 if (value.tag() == .unreachable_value)
1764 tuple_storage.appendAssumeCapacity(.{
1765 .type = fields.types[index],
1766 .value = value,
1767 });
1768
1769 const tuple_slice = tuple_storage.slice();
1770 var tuple_pl = Type.Payload.Tuple{ .data = .{
1771 .types = tuple_slice.items(.type),
1772 .values = tuple_slice.items(.value),
1773 } };
1774 const tuple_ty = Type.initPayload(&tuple_pl.base);
1775
1776 const name = dg.getTypedefName(tuple_ty) orelse
1777 try dg.renderTupleTypedef(tuple_ty);
1778
1779 try w.writeAll(name);
1780 } else if (kind == .Complete) {
17551781 const name = dg.getTypedefName(t) orelse switch (tag) {
1756 .Struct => if (t.isTupleOrAnonStruct())
1757 try dg.renderTupleTypedef(t)
1758 else
1759 try dg.renderStructTypedef(t),
1782 .Struct => try dg.renderStructTypedef(t),
17601783 .Union => try dg.renderUnionTypedef(t),
17611784 else => unreachable,
17621785 };
......@@ -1976,6 +1999,7 @@ pub const DeclGen = struct {
19761999 .local_ref => |i| return w.print("&t{d}", .{i}),
19772000 .constant => unreachable,
19782001 .arg => |i| return w.print("a{d}", .{i}),
2002 .field => |i| return w.print("f{d}", .{i}),
19792003 .decl => |decl| return dg.renderDeclName(w, decl),
19802004 .decl_ref => |decl| {
19812005 try w.writeByte('&');
......@@ -1994,6 +2018,7 @@ pub const DeclGen = struct {
19942018 .local_ref => |i| return w.print("t{d}", .{i}),
19952019 .constant => unreachable,
19962020 .arg => |i| return w.print("(*a{d})", .{i}),
2021 .field => |i| return w.print("f{d}", .{i}),
19972022 .decl => |decl| {
19982023 try w.writeAll("(*");
19992024 try dg.renderDeclName(w, decl);
......@@ -2018,7 +2043,7 @@ pub const DeclGen = struct {
20182043
20192044 fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
20202045 switch (c_value) {
2021 .none, .constant, .undef => unreachable,
2046 .none, .constant, .field, .undef => unreachable,
20222047 .local, .arg, .decl, .identifier, .bytes => {
20232048 try dg.writeCValue(writer, c_value);
20242049 try writer.writeAll("->");
......@@ -2236,12 +2261,6 @@ pub fn genDecl(o: *Object) !void {
22362261 const variable: *Module.Var = var_payload.data;
22372262 const is_global = o.dg.declIsGlobal(tv) or variable.is_extern;
22382263 const fwd_decl_writer = o.dg.fwd_decl.writer();
2239 if (is_global) {
2240 try fwd_decl_writer.writeAll("zig_extern_c ");
2241 }
2242 if (variable.is_threadlocal) {
2243 try fwd_decl_writer.writeAll("zig_threadlocal ");
2244 }
22452264
22462265 const decl_c_value: CValue = if (is_global) .{
22472266 .bytes = mem.span(o.dg.decl.name),
......@@ -2249,6 +2268,8 @@ pub fn genDecl(o: *Object) !void {
22492268 .decl = o.dg.decl_index,
22502269 };
22512270
2271 if (is_global) try fwd_decl_writer.writeAll("zig_extern_c ");
2272 if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal ");
22522273 try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
22532274 try fwd_decl_writer.writeAll(";\n");
22542275
......@@ -2257,6 +2278,7 @@ pub fn genDecl(o: *Object) !void {
22572278 }
22582279
22592280 const w = o.writer();
2281 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
22602282 try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
22612283 try w.writeAll(" = ");
22622284 if (variable.init.tag() != .unreachable_value) {
......@@ -2595,19 +2617,36 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
25952617}
25962618
25972619fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2620 const inst_ty = f.air.typeOfIndex(inst);
25982621 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
25992622 const ptr_ty = f.air.typeOf(bin_op.lhs);
2600 if (!ptr_ty.isVolatilePtr() and f.liveness.isUnused(inst)) return CValue.none;
2623 if ((!ptr_ty.isVolatilePtr() and f.liveness.isUnused(inst)) or
2624 !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none;
26012625
26022626 const ptr = try f.resolveInst(bin_op.lhs);
26032627 const index = try f.resolveInst(bin_op.rhs);
2628
2629 const target = f.object.dg.module.getTarget();
2630 const is_array = lowersToArray(inst_ty, target);
2631
2632 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
26042633 const writer = f.object.writer();
2605 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2606 try writer.writeAll(" = ");
2634 if (is_array) {
2635 try writer.writeAll(";\n");
2636 try writer.writeAll("memcpy(");
2637 try f.writeCValue(writer, local, .FunctionArgument);
2638 try writer.writeAll(", ");
2639 } else try writer.writeAll(" = ");
26072640 try f.writeCValue(writer, ptr, .Other);
26082641 try writer.writeByte('[');
26092642 try f.writeCValue(writer, index, .Other);
2610 try writer.writeAll("];\n");
2643 try writer.writeByte(']');
2644 if (is_array) {
2645 try writer.writeAll(", sizeof(");
2646 try f.renderTypecast(writer, inst_ty);
2647 try writer.writeAll("))");
2648 }
2649 try writer.writeAll(";\n");
26112650 return local;
26122651}
26132652
......@@ -2637,19 +2676,36 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
26372676}
26382677
26392678fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2679 const inst_ty = f.air.typeOfIndex(inst);
26402680 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
26412681 const slice_ty = f.air.typeOf(bin_op.lhs);
2642 if (!slice_ty.isVolatilePtr() and f.liveness.isUnused(inst)) return CValue.none;
2682 if ((!slice_ty.isVolatilePtr() and f.liveness.isUnused(inst)) or
2683 !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none;
26432684
26442685 const slice = try f.resolveInst(bin_op.lhs);
26452686 const index = try f.resolveInst(bin_op.rhs);
2687
2688 const target = f.object.dg.module.getTarget();
2689 const is_array = lowersToArray(inst_ty, target);
2690
2691 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
26462692 const writer = f.object.writer();
2647 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2648 try writer.writeAll(" = ");
2693 if (is_array) {
2694 try writer.writeAll(";\n");
2695 try writer.writeAll("memcpy(");
2696 try f.writeCValue(writer, local, .FunctionArgument);
2697 try writer.writeAll(", ");
2698 } else try writer.writeAll(" = ");
26492699 try f.writeCValue(writer, slice, .Other);
26502700 try writer.writeAll(".ptr[");
26512701 try f.writeCValue(writer, index, .Other);
2652 try writer.writeAll("];\n");
2702 try writer.writeByte(']');
2703 if (is_array) {
2704 try writer.writeAll(", sizeof(");
2705 try f.renderTypecast(writer, inst_ty);
2706 try writer.writeAll("))");
2707 }
2708 try writer.writeAll(";\n");
26532709 return local;
26542710}
26552711
......@@ -2672,18 +2728,34 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
26722728}
26732729
26742730fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2675 if (f.liveness.isUnused(inst)) return CValue.none;
2731 const inst_ty = f.air.typeOfIndex(inst);
2732 if (f.liveness.isUnused(inst) or !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none;
26762733
26772734 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
26782735 const array = try f.resolveInst(bin_op.lhs);
26792736 const index = try f.resolveInst(bin_op.rhs);
2737
2738 const target = f.object.dg.module.getTarget();
2739 const is_array = lowersToArray(inst_ty, target);
2740
2741 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
26802742 const writer = f.object.writer();
2681 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2682 try writer.writeAll(" = ");
2743 if (is_array) {
2744 try writer.writeAll(";\n");
2745 try writer.writeAll("memcpy(");
2746 try f.writeCValue(writer, local, .FunctionArgument);
2747 try writer.writeAll(", ");
2748 } else try writer.writeAll(" = ");
26832749 try f.writeCValue(writer, array, .Other);
26842750 try writer.writeByte('[');
26852751 try f.writeCValue(writer, index, .Other);
2686 try writer.writeAll("];\n");
2752 try writer.writeByte(']');
2753 if (is_array) {
2754 try writer.writeAll(", sizeof(");
2755 try f.renderTypecast(writer, inst_ty);
2756 try writer.writeAll("))");
2757 }
2758 try writer.writeAll(";\n");
26872759 return local;
26882760}
26892761
......@@ -2817,7 +2889,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
28172889 const array_local = try f.allocLocal(lowered_ret_ty, .Mut);
28182890 try writer.writeAll(";\n");
28192891 try writer.writeAll("memcpy(");
2820 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });
2892 try f.writeCValueMember(writer, array_local, .{ .field = 0 });
28212893 try writer.writeAll(", ");
28222894 if (deref)
28232895 try f.writeCValueDeref(writer, operand)
......@@ -3063,13 +3135,13 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
30633135 const local = try f.allocLocal(inst_ty, .Mut);
30643136 try w.writeAll(";\n");
30653137
3066 try f.writeCValue(w, local, .Other);
3067 try w.writeAll(".field_1 = zig_");
3138 try f.writeCValueMember(w, local, .{ .field = 1 });
3139 try w.writeAll(" = zig_");
30683140 try w.writeAll(operation);
30693141 try w.writeAll("o_");
30703142 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
30713143 try w.writeAll("(&");
3072 try f.writeCValueMember(w, local, .{ .identifier = "field_0" });
3144 try f.writeCValueMember(w, local, .{ .field = 0 });
30733145 try w.writeAll(", ");
30743146 try f.writeCValue(w, lhs, .FunctionArgument);
30753147 try w.writeAll(", ");
......@@ -3191,7 +3263,7 @@ fn airEquality(
31913263
31923264 try writer.writeAll(" = ");
31933265
3194 if (operand_ty.tag() == .optional) {
3266 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.isPtrLikeOptional()) {
31953267 // (A && B) || (C && (A == B))
31963268 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
31973269
......@@ -3429,7 +3501,7 @@ fn airCall(
34293501 try writer.writeAll("memcpy(");
34303502 try f.writeCValue(writer, array_local, .FunctionArgument);
34313503 try writer.writeAll(", ");
3432 try f.writeCValueMember(writer, result_local, .{ .identifier = "array" });
3504 try f.writeCValueMember(writer, result_local, .{ .field = 0 });
34333505 try writer.writeAll(", sizeof(");
34343506 try f.renderTypecast(writer, ret_ty);
34353507 try writer.writeAll("));\n");
......@@ -3590,25 +3662,39 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
35903662 // If result is .none then the value of the block is unused.
35913663 if (result != .none) {
35923664 const operand = try f.resolveInst(branch.operand);
3593 try f.writeCValue(writer, result, .Other);
3594 try writer.writeAll(" = ");
3595 try f.writeCValue(writer, operand, .Other);
3665
3666 const operand_ty = f.air.typeOf(branch.operand);
3667 const target = f.object.dg.module.getTarget();
3668 if (lowersToArray(operand_ty, target)) {
3669 try writer.writeAll("memcpy(");
3670 try f.writeCValue(writer, result, .FunctionArgument);
3671 try writer.writeAll(", ");
3672 try f.writeCValue(writer, operand, .FunctionArgument);
3673 try writer.writeAll(", sizeof(");
3674 try f.renderTypecast(writer, operand_ty);
3675 try writer.writeAll("))");
3676 } else {
3677 try f.writeCValue(writer, result, .Other);
3678 try writer.writeAll(" = ");
3679 try f.writeCValue(writer, operand, .Other);
3680 }
35963681 try writer.writeAll(";\n");
35973682 }
35983683
3599 try f.object.writer().print("goto zig_block_{d};\n", .{block.block_id});
3684 try writer.print("goto zig_block_{d};\n", .{block.block_id});
36003685 return CValue.none;
36013686}
36023687
36033688fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
3604 if (f.liveness.isUnused(inst))
3605 return CValue.none;
3689 const inst_ty = f.air.typeOfIndex(inst);
3690 // No IgnoreComptime until Sema stops giving us garbage Air.
3691 // https://github.com/ziglang/zig/issues/13410
3692 if (f.liveness.isUnused(inst) or !inst_ty.hasRuntimeBits()) return CValue.none;
36063693
36073694 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
36083695 const operand = try f.resolveInst(ty_op.operand);
36093696
36103697 const writer = f.object.writer();
3611 const inst_ty = f.air.typeOfIndex(inst);
36123698 if (inst_ty.isPtrAtRuntime() and
36133699 f.air.typeOf(ty_op.operand).isPtrAtRuntime())
36143700 {
......@@ -3982,9 +4068,9 @@ fn airIsNull(
39824068
39834069 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime())
39844070 TypedValue{ .ty = Type.bool, .val = Value.@"true" }
3985 else if (operand_ty.isPtrLikeOptional())
4071 else if (optional_ty.isPtrLikeOptional())
39864072 // operand is a regular pointer, test `operand !=/== NULL`
3987 TypedValue{ .ty = operand_ty, .val = Value.@"null" }
4073 TypedValue{ .ty = optional_ty, .val = Value.@"null" }
39884074 else if (payload_ty.zigTypeTag() == .ErrorSet)
39894075 TypedValue{ .ty = payload_ty, .val = Value.zero }
39904076 else if (payload_ty.isSlice() and optional_ty.optionalReprIsPayload()) rhs: {
......@@ -4007,26 +4093,34 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
40074093 if (f.liveness.isUnused(inst)) return CValue.none;
40084094
40094095 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
4010 const writer = f.object.writer();
40114096 const operand = try f.resolveInst(ty_op.operand);
40124097 const opt_ty = f.air.typeOf(ty_op.operand);
40134098
40144099 var buf: Type.Payload.ElemType = undefined;
40154100 const payload_ty = opt_ty.optionalChild(&buf);
40164101
4017 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4018 return CValue.none;
4019 }
4020
4021 if (opt_ty.optionalReprIsPayload()) {
4022 return operand;
4023 }
4102 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none;
4103 if (opt_ty.optionalReprIsPayload()) return operand;
40244104
40254105 const inst_ty = f.air.typeOfIndex(inst);
4026 const local = try f.allocLocal(inst_ty, .Const);
4027 try writer.writeAll(" = (");
4028 try f.writeCValue(writer, operand, .Other);
4029 try writer.writeAll(").payload;\n");
4106 const target = f.object.dg.module.getTarget();
4107 const is_array = lowersToArray(inst_ty, target);
4108
4109 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
4110 const writer = f.object.writer();
4111 if (is_array) {
4112 try writer.writeAll(";\n");
4113 try writer.writeAll("memcpy(");
4114 try f.writeCValue(writer, local, .FunctionArgument);
4115 try writer.writeAll(", ");
4116 } else try writer.writeAll(" = ");
4117 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
4118 if (is_array) {
4119 try writer.writeAll(", sizeof(");
4120 try f.renderTypecast(writer, inst_ty);
4121 try writer.writeAll("))");
4122 }
4123 try writer.writeAll(";\n");
40304124 return local;
40314125}
40324126
......@@ -4159,16 +4253,14 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
41594253 try f.renderTypecast(writer, field_ptr_ty);
41604254 try writer.writeByte(')');
41614255
4162 const extra_name: ?[]const u8 = switch (struct_ty.tag()) {
4163 .union_tagged, .union_safety_tagged => "payload",
4164 else => null,
4256 const extra_name: CValue = switch (struct_ty.tag()) {
4257 .union_tagged, .union_safety_tagged => .{ .identifier = "payload" },
4258 else => .none,
41654259 };
41664260
4167 var field_name_buf: []const u8 = &.{};
4168 defer f.object.dg.gpa.free(field_name_buf);
4169 const field_name: ?[]const u8 = switch (struct_ty.tag()) {
4261 const field_name: CValue = switch (struct_ty.tag()) {
41704262 .@"struct" => switch (struct_ty.containerLayout()) {
4171 .Auto, .Extern => struct_ty.structFieldName(index),
4263 .Auto, .Extern => CValue{ .identifier = struct_ty.structFieldName(index) },
41724264 .Packed => if (field_ptr_info.data.host_size == 0) {
41734265 const target = f.object.dg.module.getTarget();
41744266
......@@ -4189,29 +4281,35 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
41894281 try f.writeCValue(writer, struct_ptr, .Other);
41904282 try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});
41914283 return local;
4192 } else null,
4284 } else @as(CValue, CValue.none), // this @as is needed because of a stage1 bug
4285 },
4286 .@"union", .union_safety_tagged, .union_tagged => .{
4287 .identifier = struct_ty.unionFields().keys()[index],
41934288 },
4194 .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[index],
4195 .tuple, .anon_struct => |tag| field_name: {
4289 .tuple, .anon_struct => field_name: {
41964290 const tuple = struct_ty.tupleFields();
41974291 if (tuple.values[index].tag() != .unreachable_value) return CValue.none;
41984292
4199 if (tag == .anon_struct) break :field_name struct_ty.structFieldName(index);
4200
4201 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{index});
4202 break :field_name field_name_buf;
4293 var id: usize = 0;
4294 for (tuple.values[0..index]) |value|
4295 id += @boolToInt(value.tag() == .unreachable_value);
4296 break :field_name .{ .field = id };
42034297 },
42044298 else => unreachable,
42054299 };
42064300
42074301 if (field_ty.hasRuntimeBitsIgnoreComptime()) {
42084302 try writer.writeByte('&');
4209 if (extra_name orelse field_name) |name|
4210 try f.writeCValueDerefMember(writer, struct_ptr, .{ .identifier = name })
4303 if (extra_name != .none) {
4304 try f.writeCValueDerefMember(writer, struct_ptr, extra_name);
4305 if (field_name != .none) {
4306 try writer.writeByte('.');
4307 try f.writeCValue(writer, field_name, .Other);
4308 }
4309 } else if (field_name != .none)
4310 try f.writeCValueDerefMember(writer, struct_ptr, field_name)
42114311 else
42124312 try f.writeCValueDeref(writer, struct_ptr);
4213 if (extra_name) |_| if (field_name) |name|
4214 try writer.print(".{ }", .{fmtIdent(name)});
42154313 } else try f.writeCValue(writer, struct_ptr, .Other);
42164314 try writer.writeAll(";\n");
42174315 return local;
......@@ -4221,9 +4319,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
42214319 if (f.liveness.isUnused(inst))
42224320 return CValue.none;
42234321
4322 const inst_ty = f.air.typeOfIndex(inst);
4323 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none;
4324
42244325 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
42254326 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
4226 const inst_ty = f.air.typeOfIndex(inst);
42274327 const target = f.object.dg.module.getTarget();
42284328 const struct_byval = try f.resolveInst(extra.struct_operand);
42294329 const struct_ty = f.air.typeOf(extra.struct_operand);
......@@ -4232,11 +4332,14 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
42324332 // Ensure complete type definition is visible before accessing fields.
42334333 try f.renderType(std.io.null_writer, struct_ty);
42344334
4235 var field_name_buf: []const u8 = "";
4236 defer f.object.dg.gpa.free(field_name_buf);
4237 const field_name = switch (struct_ty.tag()) {
4335 const extra_name: CValue = switch (struct_ty.tag()) {
4336 .union_tagged, .union_safety_tagged => .{ .identifier = "payload" },
4337 else => .none,
4338 };
4339
4340 const field_name: CValue = switch (struct_ty.tag()) {
42384341 .@"struct" => switch (struct_ty.containerLayout()) {
4239 .Auto, .Extern => struct_ty.structFieldName(extra.field_index),
4342 .Auto, .Extern => .{ .identifier = struct_ty.structFieldName(extra.field_index) },
42404343 .Packed => {
42414344 const struct_obj = struct_ty.castTag(.@"struct").?.data;
42424345 const int_info = struct_ty.intInfo(target);
......@@ -4294,19 +4397,20 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
42944397 return local;
42954398 },
42964399 },
4297 .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[extra.field_index],
4298 .tuple, .anon_struct => |tag| blk: {
4400 .@"union", .union_safety_tagged, .union_tagged => .{
4401 .identifier = struct_ty.unionFields().keys()[extra.field_index],
4402 },
4403 .tuple, .anon_struct => blk: {
42994404 const tuple = struct_ty.tupleFields();
43004405 if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none;
43014406
4302 if (tag == .anon_struct) break :blk struct_ty.structFieldName(extra.field_index);
4303
4304 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{extra.field_index});
4305 break :blk field_name_buf;
4407 var id: usize = 0;
4408 for (tuple.values[0..extra.field_index]) |value|
4409 id += @boolToInt(value.tag() == .unreachable_value);
4410 break :blk .{ .field = id };
43064411 },
43074412 else => unreachable,
43084413 };
4309 const payload = if (struct_ty.tag() == .union_tagged or struct_ty.tag() == .union_safety_tagged) "payload." else "";
43104414
43114415 const is_array = lowersToArray(inst_ty, target);
43124416 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
......@@ -4315,15 +4419,18 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
43154419 try writer.writeAll("memcpy(");
43164420 try f.writeCValue(writer, local, .FunctionArgument);
43174421 try writer.writeAll(", ");
4318 try f.writeCValue(writer, struct_byval, .Other);
4319 try writer.print(".{s}{ }, sizeof(", .{ payload, fmtIdent(field_name) });
4422 } else try writer.writeAll(" = ");
4423 if (extra_name != .none) {
4424 try f.writeCValueMember(writer, struct_byval, extra_name);
4425 try writer.writeByte('.');
4426 try f.writeCValue(writer, field_name, .Other);
4427 } else try f.writeCValueMember(writer, struct_byval, field_name);
4428 if (is_array) {
4429 try writer.writeAll(", sizeof(");
43204430 try f.renderTypecast(writer, inst_ty);
4321 try writer.writeAll("));\n");
4322 } else {
4323 try writer.writeAll(" = ");
4324 try f.writeCValue(writer, struct_byval, .Other);
4325 try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });
4431 try writer.writeAll("))");
43264432 }
4433 try writer.writeAll(";\n");
43274434 return local;
43284435}
43294436
......@@ -4383,25 +4490,33 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
43834490}
43844491
43854492fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
4386 if (f.liveness.isUnused(inst))
4387 return CValue.none;
4493 if (f.liveness.isUnused(inst)) return CValue.none;
43884494
4495 const inst_ty = f.air.typeOfIndex(inst);
43894496 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
4390 const writer = f.object.writer();
4391 const operand = try f.resolveInst(ty_op.operand);
4497 const payload = try f.resolveInst(ty_op.operand);
4498 if (inst_ty.optionalReprIsPayload()) return payload;
43924499
4393 const inst_ty = f.air.typeOfIndex(inst);
4394 if (inst_ty.optionalReprIsPayload()) {
4395 return operand;
4396 }
4500 const payload_ty = f.air.typeOf(ty_op.operand);
4501 const target = f.object.dg.module.getTarget();
4502 const is_array = lowersToArray(payload_ty, target);
43974503
4398 // .wrap_optional is used to convert non-optionals into optionals so it can never be null.
4399 const local = try f.allocLocal(inst_ty, .Const);
4504 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
4505 const writer = f.object.writer();
44004506 try writer.writeAll(" = { .payload = ");
4401 try f.writeCValue(writer, operand, .Initializer);
4507 try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else payload, .Initializer);
44024508 try writer.writeAll(", .is_null = ");
44034509 try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer);
44044510 try writer.writeAll(" };\n");
4511 if (is_array) {
4512 try writer.writeAll("memcpy(");
4513 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
4514 try writer.writeAll(", ");
4515 try f.writeCValue(writer, payload, .FunctionArgument);
4516 try writer.writeAll(", sizeof(");
4517 try f.renderTypecast(writer, payload_ty);
4518 try writer.writeAll("));\n");
4519 }
44054520 return local;
44064521}
44074522
......@@ -4473,35 +4588,33 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
44734588}
44744589
44754590fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
4476 if (f.liveness.isUnused(inst))
4477 return CValue.none;
4478
4479 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
4480 const writer = f.object.writer();
4481 const operand = try f.resolveInst(ty_op.operand);
4591 if (f.liveness.isUnused(inst)) return CValue.none;
44824592
44834593 const inst_ty = f.air.typeOfIndex(inst);
4484 const payload_ty = inst_ty.errorUnionPayload();
44854594 const error_ty = inst_ty.errorUnionSet();
4595 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
4596 const payload_ty = inst_ty.errorUnionPayload();
4597 const payload = try f.resolveInst(ty_op.operand);
4598
44864599 const target = f.object.dg.module.getTarget();
44874600 const is_array = lowersToArray(payload_ty, target);
4601
44884602 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
4603 const writer = f.object.writer();
44894604 try writer.writeAll(" = { .payload = ");
4490 try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else operand, .Initializer);
4605 try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else payload, .Initializer);
44914606 try writer.writeAll(", .error = ");
44924607 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
44934608 try writer.writeAll(" };\n");
4494
44954609 if (is_array) {
44964610 try writer.writeAll("memcpy(");
4497 try f.writeCValue(writer, local, .Other);
4498 try writer.writeAll(".payload, ");
4499 try f.writeCValue(writer, operand, .FunctionArgument);
4611 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
4612 try writer.writeAll(", ");
4613 try f.writeCValue(writer, payload, .FunctionArgument);
45004614 try writer.writeAll(", sizeof(");
45014615 try f.renderTypecast(writer, payload_ty);
45024616 try writer.writeAll("));\n");
45034617 }
4504
45054618 return local;
45064619}
45074620
......@@ -4845,10 +4958,41 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
48454958fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue {
48464959 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
48474960 const extra = f.air.extraData(Air.Bin, pl_op.payload).data;
4961 const dest_ty = f.air.typeOf(pl_op.operand);
48484962 const dest_ptr = try f.resolveInst(pl_op.operand);
48494963 const value = try f.resolveInst(extra.lhs);
48504964 const len = try f.resolveInst(extra.rhs);
4965
48514966 const writer = f.object.writer();
4967 if (dest_ty.isVolatilePtr()) {
4968 var u8_ptr_pl = dest_ty.ptrInfo();
4969 u8_ptr_pl.data.pointee_type = Type.u8;
4970 const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base);
4971
4972 try writer.writeAll("for (");
4973 const index = try f.allocLocal(Type.usize, .Mut);
4974 try writer.writeAll(" = ");
4975 try f.object.dg.renderValue(writer, Type.usize, Value.zero, .Initializer);
4976 try writer.writeAll("; ");
4977 try f.writeCValue(writer, index, .Other);
4978 try writer.writeAll(" != ");
4979 try f.writeCValue(writer, len, .Other);
4980 try writer.writeAll("; ");
4981 try f.writeCValue(writer, index, .Other);
4982 try writer.writeAll(" += ");
4983 try f.object.dg.renderValue(writer, Type.usize, Value.one, .Other);
4984 try writer.writeAll(") ((");
4985 try f.renderTypecast(writer, u8_ptr_ty);
4986 try writer.writeByte(')');
4987 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
4988 try writer.writeAll(")[");
4989 try f.writeCValue(writer, index, .Other);
4990 try writer.writeAll("] = ");
4991 try f.writeCValue(writer, value, .FunctionArgument);
4992 try writer.writeAll(";\n");
4993
4994 return CValue.none;
4995 }
48524996
48534997 try writer.writeAll("memset(");
48544998 try f.writeCValue(writer, dest_ptr, .FunctionArgument);
......@@ -5068,27 +5212,28 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
50685212 if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
50695213 try writer.writeAll("};\n");
50705214
5215 var field_id: usize = 0;
50715216 for (elements) |element, index| {
50725217 if (inst_ty.structFieldValueComptime(index)) |_| continue;
50735218
50745219 const element_ty = f.air.typeOf(element);
50755220 if (element_ty.zigTypeTag() != .Array) continue;
50765221
5077 var field_name_buf: []u8 = &.{};
5078 defer f.object.dg.gpa.free(field_name_buf);
5079 const field_name = if (inst_ty.isTuple()) field_name: {
5080 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{index});
5081 break :field_name field_name_buf;
5082 } else inst_ty.structFieldName(index);
5222 const field_name = if (inst_ty.isTupleOrAnonStruct())
5223 CValue{ .field = field_id }
5224 else
5225 CValue{ .identifier = inst_ty.structFieldName(index) };
50835226
50845227 try writer.writeAll(";\n");
50855228 try writer.writeAll("memcpy(");
5086 try f.writeCValue(writer, local, .Other);
5087 try writer.print(".{ }, ", .{fmtIdent(field_name)});
5229 try f.writeCValueMember(writer, local, field_name);
5230 try writer.writeAll(", ");
50885231 try f.writeCValue(writer, try f.resolveInst(element), .FunctionArgument);
50895232 try writer.writeAll(", sizeof(");
50905233 try f.renderTypecast(writer, element_ty);
50915234 try writer.writeAll("));\n");
5235
5236 field_id += 1;
50925237 }
50935238 },
50945239 .Packed => {
......@@ -5634,10 +5779,9 @@ fn isByRef(ty: Type) bool {
56345779}
56355780
56365781const LowerFnRetTyBuffer = struct {
5637 const names = [1][]const u8{"array"};
56385782 types: [1]Type,
56395783 values: [1]Value,
5640 payload: Type.Payload.AnonStruct,
5784 payload: Type.Payload.Tuple,
56415785};
56425786fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) Type {
56435787 if (ret_ty.zigTypeTag() == .NoReturn) return Type.initTag(.noreturn);
......@@ -5646,7 +5790,6 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) T
56465790 buffer.types = [1]Type{ret_ty};
56475791 buffer.values = [1]Value{Value.initTag(.unreachable_value)};
56485792 buffer.payload = .{ .data = .{
5649 .names = &LowerFnRetTyBuffer.names,
56505793 .types = &buffer.types,
56515794 .values = &buffer.values,
56525795 } };
test/behavior/basic.zig-1
......@@ -725,7 +725,6 @@ test "comptime manyptr concatenation" {
725725}
726726
727727test "thread local variable" {
728 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
729728 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
730729 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
731730 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/bugs/11139.zig-1
......@@ -3,7 +3,6 @@ const builtin = @import("builtin");
33const expect = std.testing.expect;
44
55test "store array of array of structs at comptime" {
6 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
87 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
98
test/behavior/bugs/1851.zig-1
......@@ -5,7 +5,6 @@ const expect = std.testing.expect;
55test "allocation and looping over 3-byte integer" {
66 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1110
test/behavior/bugs/7250.zig-1
......@@ -14,7 +14,6 @@ threadlocal var g_uart0 = nrfx_uart_t{
1414};
1515
1616test "reference a global threadlocal variable" {
17 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1817 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1918 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
2019 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/cast.zig-1
......@@ -1178,7 +1178,6 @@ fn cast128Float(x: u128) f128 {
11781178
11791179test "implicit cast from *[N]T to ?[*]T" {
11801180 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1181 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11821181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11831182 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11841183
test/behavior/fn.zig-1
......@@ -355,7 +355,6 @@ test "function call with anon list literal" {
355355}
356356
357357test "function call with anon list literal - 2D" {
358 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
359358 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
360359 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
361360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/if.zig-1
......@@ -146,7 +146,6 @@ test "result location with inferred type ends up being pointer to comptime_int"
146146 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
147147 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
148148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
149 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
150149
151150 var a: ?u32 = 1234;
152151 var b: u32 = 2000;
test/behavior/type.zig-1
......@@ -260,7 +260,6 @@ test "Type.ErrorSet" {
260260
261261test "Type.Struct" {
262262 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
263 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
264263 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
265264 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
266265 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/tests.zig+3-1
......@@ -52,6 +52,9 @@ const test_targets = blk: {
5252 },
5353
5454 .{
55 .target = .{
56 .ofmt = .c,
57 },
5558 .link_libc = true,
5659 .backend = .stage2_c,
5760 },
......@@ -720,7 +723,6 @@ pub fn addPkgTests(
720723 .stage2_c => {
721724 these_tests.use_stage1 = false;
722725 these_tests.use_llvm = false;
723 these_tests.ofmt = .c;
724726 },
725727 else => {
726728 these_tests.use_stage1 = false;