authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-08 08:54:49-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:28-04:00
log6a4266d62aacf887a81549d81ae6f312992d2b2c
treec06696c4224bebe1927779948441aed4f0808b39
parent7c9a9a0fd4560d8ce5d61ab96b9403d27dd872b3

cbe: fix infinite recursion on recursive types


23 files changed, 181 insertions(+), 152 deletions(-)

lib/include/zig.h+1
...@@ -162,6 +162,7 @@...@@ -162,6 +162,7 @@
162#include <stdint.h>162#include <stdint.h>
163#include <stddef.h>163#include <stddef.h>
164#include <limits.h>164#include <limits.h>
165#include <math.h>
165166
166#define int128_t __int128167#define int128_t __int128
167#define uint128_t unsigned __int128168#define uint128_t unsigned __int128
src/Compilation.zig+8-5
...@@ -3099,13 +3099,16 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3099,13 +3099,16 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
3099 .decl_index = decl_index,3099 .decl_index = decl_index,
3100 .decl = decl,3100 .decl = decl,
3101 .fwd_decl = fwd_decl.toManaged(gpa),3101 .fwd_decl = fwd_decl.toManaged(gpa),
3102 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{3102 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{ .mod = module }),
3103 .mod = module,
3104 }),
3105 .typedefs_arena = typedefs_arena.allocator(),3103 .typedefs_arena = typedefs_arena.allocator(),
3106 };3104 };
3107 defer dg.fwd_decl.deinit();3105 defer {
3108 defer dg.typedefs.deinit();3106 for (dg.typedefs.values()) |typedef| {
3107 module.gpa.free(typedef.rendered);
3108 }
3109 dg.typedefs.deinit();
3110 dg.fwd_decl.deinit();
3111 }
31093112
3110 c_codegen.genHeader(&dg) catch |err| switch (err) {3113 c_codegen.genHeader(&dg) catch |err| switch (err) {
3111 error.AnalysisFail => {3114 error.AnalysisFail => {
src/codegen/c.zig+140-91
...@@ -372,8 +372,8 @@ pub const DeclGen = struct {...@@ -372,8 +372,8 @@ pub const DeclGen = struct {
372 }372 }
373373
374 fn getTypedefName(dg: *DeclGen, t: Type) ?[]const u8 {374 fn getTypedefName(dg: *DeclGen, t: Type) ?[]const u8 {
375 if (dg.typedefs.get(t)) |some| {375 if (dg.typedefs.get(t)) |typedef| {
376 return some.name;376 return typedef.name;
377 } else {377 } else {
378 return null;378 return null;
379 }379 }
...@@ -1025,9 +1025,10 @@ pub const DeclGen = struct {...@@ -1025,9 +1025,10 @@ pub const DeclGen = struct {
1025 try dg.renderType(bw, fn_info.return_type);1025 try dg.renderType(bw, fn_info.return_type);
1026 try bw.writeAll(" (*");1026 try bw.writeAll(" (*");
10271027
1028 const name_start = buffer.items.len;1028 const name_begin = buffer.items.len;
1029 try bw.print("zig_F_{})(", .{typeToCIdentifier(t, dg.module)});1029 try bw.print("zig_F_{}", .{typeToCIdentifier(t, dg.module)});
1030 const name_end = buffer.items.len - 2;1030 const name_end = buffer.items.len;
1031 try bw.writeAll(")(");
10311032
1032 const param_len = fn_info.param_types.len;1033 const param_len = fn_info.param_types.len;
10331034
...@@ -1052,7 +1053,7 @@ pub const DeclGen = struct {...@@ -1052,7 +1053,7 @@ pub const DeclGen = struct {
10521053
1053 const rendered = buffer.toOwnedSlice();1054 const rendered = buffer.toOwnedSlice();
1054 errdefer dg.typedefs.allocator.free(rendered);1055 errdefer dg.typedefs.allocator.free(rendered);
1055 const name = rendered[name_start..name_end];1056 const name = rendered[name_begin..name_end];
10561057
1057 try dg.typedefs.ensureUnusedCapacity(1);1058 try dg.typedefs.ensureUnusedCapacity(1);
1058 dg.typedefs.putAssumeCapacityNoClobber(1059 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1079,12 +1080,11 @@ pub const DeclGen = struct {...@@ -1079,12 +1080,11 @@ pub const DeclGen = struct {
1079 const child_type = t.childType();1080 const child_type = t.childType();
10801081
1081 try bw.writeAll("; size_t len; } ");1082 try bw.writeAll("; size_t len; } ");
1082 const name_index = buffer.items.len;1083 const name_begin = buffer.items.len;
1083 if (t.isConstPtr()) {1084 try bw.print("zig_{c}_{}", .{
1084 try bw.print("zig_L_{}", .{typeToCIdentifier(child_type, dg.module)});1085 @as(u8, if (t.isConstPtr()) 'L' else 'M'),
1085 } else {1086 typeToCIdentifier(child_type, dg.module),
1086 try bw.print("zig_M_{}", .{typeToCIdentifier(child_type, dg.module)});1087 });
1087 }
1088 if (ptr_sentinel) |s| {1088 if (ptr_sentinel) |s| {
1089 var sentinel_buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1089 var sentinel_buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1090 defer sentinel_buffer.deinit();1090 defer sentinel_buffer.deinit();
...@@ -1092,11 +1092,12 @@ pub const DeclGen = struct {...@@ -1092,11 +1092,12 @@ pub const DeclGen = struct {
1092 try dg.renderValue(sentinel_buffer.writer(), child_type, s, .Identifier);1092 try dg.renderValue(sentinel_buffer.writer(), child_type, s, .Identifier);
1093 try bw.print("_s_{}", .{fmtIdent(sentinel_buffer.items)});1093 try bw.print("_s_{}", .{fmtIdent(sentinel_buffer.items)});
1094 }1094 }
1095 const name_end = buffer.items.len;
1095 try bw.writeAll(";\n");1096 try bw.writeAll(";\n");
10961097
1097 const rendered = buffer.toOwnedSlice();1098 const rendered = buffer.toOwnedSlice();
1098 errdefer dg.typedefs.allocator.free(rendered);1099 errdefer dg.typedefs.allocator.free(rendered);
1099 const name = rendered[name_index .. rendered.len - 2];1100 const name = rendered[name_begin..name_end];
11001101
1101 try dg.typedefs.ensureUnusedCapacity(1);1102 try dg.typedefs.ensureUnusedCapacity(1);
1102 dg.typedefs.putAssumeCapacityNoClobber(1103 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1115,7 +1116,30 @@ pub const DeclGen = struct {...@@ -1115,7 +1116,30 @@ pub const DeclGen = struct {
1115 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1116 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1116 defer buffer.deinit();1117 defer buffer.deinit();
11171118
1118 try buffer.appendSlice("typedef struct {\n");1119 const tag = "struct";
1120 const tagged_name_begin = buffer.items.len + "typedef ".len + tag.len + " ".len;
1121 try buffer.writer().print("typedef " ++ tag ++ " zig_S_{} ", .{fmtIdent(fqn)});
1122 const tagged_name_end = buffer.items.len - " ".len;
1123 try buffer.ensureUnusedCapacity(tagged_name_end - tagged_name_begin + ";\n".len);
1124 const name_begin = buffer.items.len;
1125 buffer.appendSliceAssumeCapacity(buffer.items[tagged_name_begin..tagged_name_end]);
1126 const name_end = buffer.items.len;
1127 buffer.appendSliceAssumeCapacity(";\n");
1128
1129 const rendered = buffer.toOwnedSlice();
1130 errdefer dg.typedefs.allocator.free(rendered);
1131 const tagged_name = rendered[tagged_name_begin..tagged_name_end];
1132 const name = rendered[name_begin..name_end];
1133
1134 try dg.typedefs.ensureUnusedCapacity(1);
1135 dg.typedefs.putAssumeCapacityNoClobber(
1136 try t.copy(dg.typedefs_arena),
1137 .{ .name = name, .rendered = rendered },
1138 );
1139
1140 try buffer.appendSlice(tag ++ " ");
1141 try buffer.appendSlice(tagged_name);
1142 try buffer.appendSlice(" {\n");
1119 {1143 {
1120 var it = struct_obj.fields.iterator();1144 var it = struct_obj.fields.iterator();
1121 var empty = true;1145 var empty = true;
...@@ -1124,68 +1148,63 @@ pub const DeclGen = struct {...@@ -1124,68 +1148,63 @@ pub const DeclGen = struct {
1124 if (!field_ty.hasRuntimeBits()) continue;1148 if (!field_ty.hasRuntimeBits()) continue;
11251149
1126 const alignment = entry.value_ptr.abi_align;1150 const alignment = entry.value_ptr.abi_align;
1127 const name: CValue = .{ .identifier = entry.key_ptr.* };1151 const field_name: CValue = .{ .identifier = entry.key_ptr.* };
1128 try buffer.append(' ');1152 try buffer.append(' ');
1129 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);1153 try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment);
1130 try buffer.appendSlice(";\n");1154 try buffer.appendSlice(";\n");
11311155
1132 empty = false;1156 empty = false;
1133 }1157 }
1134 if (empty) try buffer.appendSlice(" char empty_struct;\n");1158 if (empty) try buffer.appendSlice(" char empty_struct;\n");
1135 }1159 }
1136 try buffer.appendSlice("} ");1160 try buffer.appendSlice("};\n");
11371161
1138 const name_start = buffer.items.len;1162 const rendered_body = buffer.toOwnedSlice();
1139 try buffer.writer().print("zig_S_{};\n", .{fmtIdent(fqn)});1163 errdefer dg.typedefs.allocator.free(rendered_body);
1140
1141 const rendered = buffer.toOwnedSlice();
1142 errdefer dg.typedefs.allocator.free(rendered);
1143 const name = rendered[name_start .. rendered.len - 2];
11441164
1165 // We need to add another item to the TypedefMap, so we need a distinct
1166 // type that is not used anywhere, but is still uniquely associated with
1167 // this type, so use an empty struct which references our unique decls.
1145 try dg.typedefs.ensureUnusedCapacity(1);1168 try dg.typedefs.ensureUnusedCapacity(1);
1146 dg.typedefs.putAssumeCapacityNoClobber(1169 dg.typedefs.putAssumeCapacityNoClobber(
1147 try t.copy(dg.typedefs_arena),1170 try Type.Tag.empty_struct.create(dg.typedefs_arena, &struct_obj.namespace),
1148 .{ .name = name, .rendered = rendered },1171 .{ .name = undefined, .rendered = rendered_body },
1149 );1172 );
11501173
1151 return name;1174 return name;
1152 }1175 }
11531176
1154 fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1177 fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1155 const tuple = t.tupleFields();
1156
1157 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1178 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1158 defer buffer.deinit();1179 defer buffer.deinit();
1159 const writer = buffer.writer();
11601180
1161 try buffer.appendSlice("typedef struct {\n");1181 try buffer.appendSlice("typedef struct {\n");
1162 {1182 {
1183 const fields = t.tupleFields();
1163 var empty = true;1184 var empty = true;
1164 for (tuple.types) |field_ty, i| {1185 for (fields.types) |field_ty, i| {
1165 if (!field_ty.hasRuntimeBits()) continue;1186 if (!field_ty.hasRuntimeBits()) continue;
1166 const val = tuple.values[i];1187 const val = fields.values[i];
1167 if (val.tag() != .unreachable_value) continue;1188 if (val.tag() != .unreachable_value) continue;
11681189
1169 var name = std.ArrayList(u8).init(dg.gpa);1190 const field_name = try std.fmt.allocPrint(dg.typedefs.allocator, "field_{d}", .{i});
1170 defer name.deinit();1191 defer dg.typedefs.allocator.free(field_name);
1171 try name.writer().print("field_{d}", .{i});
11721192
1173 try buffer.append(' ');1193 try buffer.append(' ');
1174 try dg.renderTypeAndName(writer, field_ty, .{ .bytes = name.items }, .Mut, 0);1194 try dg.renderTypeAndName(buffer.writer(), field_ty, .{ .identifier = field_name }, .Mut, 0);
1175 try buffer.appendSlice(";\n");1195 try buffer.appendSlice(";\n");
11761196
1177 empty = false;1197 empty = false;
1178 }1198 }
1179 if (empty) try buffer.appendSlice(" char empty_tuple;\n");1199 if (empty) try buffer.appendSlice(" char empty_tuple;\n");
1180 }1200 }
1181 try buffer.appendSlice("} ");1201 const name_begin = buffer.items.len + "} ".len;
11821202 try buffer.writer().print("}} zig_T_{};\n", .{typeToCIdentifier(t, dg.module)});
1183 const name_start = buffer.items.len;1203 const name_end = buffer.items.len - ";\n".len;
1184 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, dg.module)});
11851204
1186 const rendered = buffer.toOwnedSlice();1205 const rendered = buffer.toOwnedSlice();
1187 errdefer dg.typedefs.allocator.free(rendered);1206 errdefer dg.typedefs.allocator.free(rendered);
1188 const name = rendered[name_start .. rendered.len - 2];1207 const name = rendered[name_begin..name_end];
11891208
1190 try dg.typedefs.ensureUnusedCapacity(1);1209 try dg.typedefs.ensureUnusedCapacity(1);
1191 dg.typedefs.putAssumeCapacityNoClobber(1210 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1197,62 +1216,85 @@ pub const DeclGen = struct {...@@ -1197,62 +1216,85 @@ pub const DeclGen = struct {
1197 }1216 }
11981217
1199 fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1218 fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1200 const union_ty = t.cast(Type.Payload.Union).?.data;1219 const union_obj = t.cast(Type.Payload.Union).?.data;
1201 const fqn = try union_ty.getFullyQualifiedName(dg.module);1220 const fqn = try union_obj.getFullyQualifiedName(dg.module);
1202 defer dg.typedefs.allocator.free(fqn);1221 defer dg.typedefs.allocator.free(fqn);
12031222
1204 const target = dg.module.getTarget();
1205 const layout = t.unionGetLayout(target);
1206
1207 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1223 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1208 defer buffer.deinit();1224 defer buffer.deinit();
12091225
1210 try buffer.appendSlice("typedef ");1226 const tag: []const u8 = if (t.unionTagTypeSafety()) |_| "struct" else "union";
1211 if (t.unionTagTypeSafety()) |tag_ty| {1227 const tagged_name_begin = buffer.items.len + "typedef ".len + tag.len + " ".len;
1212 const name: CValue = .{ .bytes = "tag" };1228 try buffer.writer().print("typedef {s} zig_S_{} ", .{ tag, fmtIdent(fqn) });
1213 try buffer.appendSlice("struct {\n ");1229 const tagged_name_end = buffer.items.len - " ".len;
1230 try buffer.ensureUnusedCapacity(tagged_name_end - tagged_name_begin + ";\n".len);
1231 const name_begin = buffer.items.len;
1232 buffer.appendSliceAssumeCapacity(buffer.items[tagged_name_begin..tagged_name_end]);
1233 const name_end = buffer.items.len;
1234 buffer.appendSliceAssumeCapacity(";\n");
1235
1236 const rendered = buffer.toOwnedSlice();
1237 errdefer dg.typedefs.allocator.free(rendered);
1238 const tagged_name = rendered[tagged_name_begin..tagged_name_end];
1239 const name = rendered[name_begin..name_end];
1240
1241 try dg.typedefs.ensureUnusedCapacity(1);
1242 dg.typedefs.putAssumeCapacityNoClobber(
1243 try t.copy(dg.typedefs_arena),
1244 .{ .name = name, .rendered = rendered },
1245 );
1246
1247 try buffer.appendSlice(tag);
1248 try buffer.append(' ');
1249 try buffer.appendSlice(tagged_name);
1250 try buffer.appendSlice(" {\n");
1251
1252 const indent = if (t.unionTagTypeSafety()) |tag_ty| indent: {
1253 const target = dg.module.getTarget();
1254 const layout = t.unionGetLayout(target);
1214 if (layout.tag_size != 0) {1255 if (layout.tag_size != 0) {
1215 try dg.renderTypeAndName(buffer.writer(), tag_ty, name, .Mut, 0);1256 try buffer.append(' ');
1257 try dg.renderTypeAndName(buffer.writer(), tag_ty, .{ .identifier = "tag" }, .Mut, 0);
1216 try buffer.appendSlice(";\n");1258 try buffer.appendSlice(";\n");
1217 }1259 }
1218 }1260 try buffer.appendSlice(" union {\n");
1261 break :indent " ";
1262 } else " ";
12191263
1220 try buffer.appendSlice("union {\n");
1221 const fields = t.unionFields();
1222 {1264 {
1223 var it = fields.iterator();1265 var it = t.unionFields().iterator();
1224 var empty = true;1266 var empty = true;
1225 while (it.next()) |entry| {1267 while (it.next()) |entry| {
1226 const field_ty = entry.value_ptr.ty;1268 const field_ty = entry.value_ptr.ty;
1227 if (!field_ty.hasRuntimeBits()) continue;1269 if (!field_ty.hasRuntimeBits()) continue;
12281270
1229 const alignment = entry.value_ptr.abi_align;1271 const alignment = entry.value_ptr.abi_align;
1230 const name: CValue = .{ .identifier = entry.key_ptr.* };1272 const field_name: CValue = .{ .identifier = entry.key_ptr.* };
1231 try buffer.append(' ');1273 try buffer.appendSlice(indent);
1232 try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment);1274 try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment);
1233 try buffer.appendSlice(";\n");1275 try buffer.appendSlice(";\n");
12341276
1235 empty = false;1277 empty = false;
1236 }1278 }
1237 if (empty) try buffer.appendSlice(" char empty_union;\n");1279 if (empty) {
1238 }1280 try buffer.appendSlice(indent);
1239 try buffer.appendSlice("} ");1281 try buffer.appendSlice("char empty_union;\n");
12401282 }
1241 if (t.unionTagTypeSafety()) |_| {
1242 try buffer.appendSlice("payload;\n} ");
1243 }1283 }
12441284
1245 const name_start = buffer.items.len;1285 if (t.unionTagTypeSafety()) |_| try buffer.appendSlice(" } payload;\n");
1246 try buffer.writer().print("zig_U_{};\n", .{fmtIdent(fqn)});1286 try buffer.appendSlice("};\n");
12471287
1248 const rendered = buffer.toOwnedSlice();1288 const rendered_body = buffer.toOwnedSlice();
1249 errdefer dg.typedefs.allocator.free(rendered);1289 errdefer dg.typedefs.allocator.free(rendered_body);
1250 const name = rendered[name_start .. rendered.len - 2];
12511290
1291 // We need to add another item to the TypedefMap, so we need a distinct
1292 // type that is not used anywhere, but is still uniquely associated with
1293 // this type, so use an empty struct which references our unique decls.
1252 try dg.typedefs.ensureUnusedCapacity(1);1294 try dg.typedefs.ensureUnusedCapacity(1);
1253 dg.typedefs.putAssumeCapacityNoClobber(1295 dg.typedefs.putAssumeCapacityNoClobber(
1254 try t.copy(dg.typedefs_arena),1296 try Type.Tag.empty_struct.create(dg.typedefs_arena, &union_obj.namespace),
1255 .{ .name = name, .rendered = rendered },1297 .{ .name = undefined, .rendered = rendered_body },
1256 );1298 );
12571299
1258 return name;1300 return name;
...@@ -1280,21 +1322,22 @@ pub const DeclGen = struct {...@@ -1280,21 +1322,22 @@ pub const DeclGen = struct {
1280 try bw.writeAll("; } ");1322 try bw.writeAll("; } ");
1281 }1323 }
12821324
1283 const name_index = buffer.items.len;1325 const name_begin = buffer.items.len;
1284 if (error_ty.castTag(.error_set_inferred)) |inf_err_set_payload| {1326 if (error_ty.castTag(.error_set_inferred)) |inf_err_set_payload| {
1285 const func = inf_err_set_payload.data.func;1327 const func = inf_err_set_payload.data.func;
1286 try bw.writeAll("zig_E_");1328 try bw.writeAll("zig_E_");
1287 try dg.renderDeclName(bw, func.owner_decl);1329 try dg.renderDeclName(bw, func.owner_decl);
1288 try bw.writeAll(";\n");
1289 } else {1330 } else {
1290 try bw.print("zig_E_{}_{};\n", .{1331 try bw.print("zig_E_{}_{}", .{
1291 typeToCIdentifier(error_ty, dg.module), typeToCIdentifier(payload_ty, dg.module),1332 typeToCIdentifier(error_ty, dg.module), typeToCIdentifier(payload_ty, dg.module),
1292 });1333 });
1293 }1334 }
1335 const name_end = buffer.items.len;
1336 try bw.writeAll(";\n");
12941337
1295 const rendered = buffer.toOwnedSlice();1338 const rendered = buffer.toOwnedSlice();
1296 errdefer dg.typedefs.allocator.free(rendered);1339 errdefer dg.typedefs.allocator.free(rendered);
1297 const name = rendered[name_index .. rendered.len - 2];1340 const name = rendered[name_begin..name_end];
12981341
1299 try dg.typedefs.ensureUnusedCapacity(1);1342 try dg.typedefs.ensureUnusedCapacity(1);
1300 dg.typedefs.putAssumeCapacityNoClobber(1343 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1315,7 +1358,7 @@ pub const DeclGen = struct {...@@ -1315,7 +1358,7 @@ pub const DeclGen = struct {
1315 try bw.writeAll("typedef ");1358 try bw.writeAll("typedef ");
1316 try dg.renderType(bw, elem_type);1359 try dg.renderType(bw, elem_type);
13171360
1318 const name_start = buffer.items.len + 1;1361 const name_begin = buffer.items.len + " ".len;
1319 try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(elem_type, dg.module), t.arrayLen() });1362 try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(elem_type, dg.module), t.arrayLen() });
1320 if (t.sentinel()) |s| {1363 if (t.sentinel()) |s| {
1321 var sentinel_buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1364 var sentinel_buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
...@@ -1331,7 +1374,7 @@ pub const DeclGen = struct {...@@ -1331,7 +1374,7 @@ pub const DeclGen = struct {
13311374
1332 const rendered = buffer.toOwnedSlice();1375 const rendered = buffer.toOwnedSlice();
1333 errdefer dg.typedefs.allocator.free(rendered);1376 errdefer dg.typedefs.allocator.free(rendered);
1334 const name = rendered[name_start..name_end];1377 const name = rendered[name_begin..name_end];
13351378
1336 try dg.typedefs.ensureUnusedCapacity(1);1379 try dg.typedefs.ensureUnusedCapacity(1);
1337 dg.typedefs.putAssumeCapacityNoClobber(1380 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1351,12 +1394,15 @@ pub const DeclGen = struct {...@@ -1351,12 +1394,15 @@ pub const DeclGen = struct {
1351 const payload_name = CValue{ .bytes = "payload" };1394 const payload_name = CValue{ .bytes = "payload" };
1352 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1395 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
1353 try bw.writeAll("; bool is_null; } ");1396 try bw.writeAll("; bool is_null; } ");
1354 const name_index = buffer.items.len;1397
1355 try bw.print("zig_Q_{};\n", .{typeToCIdentifier(child_type, dg.module)});1398 const name_begin = buffer.items.len;
1399 try bw.print("zig_Q_{}", .{typeToCIdentifier(child_type, dg.module)});
1400 const name_end = buffer.items.len;
1401 try bw.writeAll(";\n");
13561402
1357 const rendered = buffer.toOwnedSlice();1403 const rendered = buffer.toOwnedSlice();
1358 errdefer dg.typedefs.allocator.free(rendered);1404 errdefer dg.typedefs.allocator.free(rendered);
1359 const name = rendered[name_index .. rendered.len - 2];1405 const name = rendered[name_begin..name_end];
13601406
1361 try dg.typedefs.ensureUnusedCapacity(1);1407 try dg.typedefs.ensureUnusedCapacity(1);
1362 dg.typedefs.putAssumeCapacityNoClobber(1408 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1378,12 +1424,14 @@ pub const DeclGen = struct {...@@ -1378,12 +1424,14 @@ pub const DeclGen = struct {
13781424
1379 try buffer.writer().print("typedef struct { } ", .{fmtIdent(std.mem.span(unqualified_name))});1425 try buffer.writer().print("typedef struct { } ", .{fmtIdent(std.mem.span(unqualified_name))});
13801426
1381 const name_start = buffer.items.len;1427 const name_begin = buffer.items.len;
1382 try buffer.writer().print("zig_O_{};\n", .{fmtIdent(fqn)});1428 try buffer.writer().print("zig_O_{}", .{fmtIdent(fqn)});
1429 const name_end = buffer.items.len;
1430 try buffer.appendSlice(";\n");
13831431
1384 const rendered = buffer.toOwnedSlice();1432 const rendered = buffer.toOwnedSlice();
1385 errdefer dg.typedefs.allocator.free(rendered);1433 errdefer dg.typedefs.allocator.free(rendered);
1386 const name = rendered[name_start .. rendered.len - 2];1434 const name = rendered[name_begin..name_end];
13871435
1388 try dg.typedefs.ensureUnusedCapacity(1);1436 try dg.typedefs.ensureUnusedCapacity(1);
1389 dg.typedefs.putAssumeCapacityNoClobber(1437 dg.typedefs.putAssumeCapacityNoClobber(
...@@ -1530,7 +1578,7 @@ pub const DeclGen = struct {...@@ -1530,7 +1578,7 @@ pub const DeclGen = struct {
1530 return w.writeAll(name);1578 return w.writeAll(name);
1531 },1579 },
1532 .Struct => {1580 .Struct => {
1533 const name = dg.getTypedefName(t) orelse if (t.isTuple() or t.tag() == .anon_struct)1581 const name = dg.getTypedefName(t) orelse if (t.isTupleOrAnonStruct())
1534 try dg.renderTupleTypedef(t)1582 try dg.renderTupleTypedef(t)
1535 else1583 else
1536 try dg.renderStructTypedef(t);1584 try dg.renderStructTypedef(t);
...@@ -3597,8 +3645,8 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc...@@ -3597,8 +3645,8 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
3597 var field_name: []const u8 = undefined;3645 var field_name: []const u8 = undefined;
3598 var field_val_ty: Type = undefined;3646 var field_val_ty: Type = undefined;
35993647
3600 var buf = std.ArrayList(u8).init(f.object.dg.gpa);3648 var field_name_buf: []const u8 = "";
3601 defer buf.deinit();3649 defer f.object.dg.gpa.free(field_name_buf);
3602 switch (struct_ty.tag()) {3650 switch (struct_ty.tag()) {
3603 .@"struct" => {3651 .@"struct" => {
3604 const fields = struct_ty.structFields();3652 const fields = struct_ty.structFields();
...@@ -3614,8 +3662,8 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc...@@ -3614,8 +3662,8 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
3614 const tuple = struct_ty.tupleFields();3662 const tuple = struct_ty.tupleFields();
3615 if (tuple.values[index].tag() != .unreachable_value) return CValue.none;3663 if (tuple.values[index].tag() != .unreachable_value) return CValue.none;
36163664
3617 try buf.writer().print("field_{d}", .{index});3665 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{index});
3618 field_name = buf.items;3666 field_name = field_name_buf;
3619 field_val_ty = tuple.types[index];3667 field_val_ty = tuple.types[index];
3620 },3668 },
3621 else => unreachable,3669 else => unreachable,
...@@ -3648,8 +3696,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3648,8 +3696,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
3648 const writer = f.object.writer();3696 const writer = f.object.writer();
3649 const struct_byval = try f.resolveInst(extra.struct_operand);3697 const struct_byval = try f.resolveInst(extra.struct_operand);
3650 const struct_ty = f.air.typeOf(extra.struct_operand);3698 const struct_ty = f.air.typeOf(extra.struct_operand);
3651 var buf = std.ArrayList(u8).init(f.object.dg.gpa);3699 var field_name_buf: []const u8 = "";
3652 defer buf.deinit();3700 defer f.object.dg.gpa.free(field_name_buf);
3653 const field_name = switch (struct_ty.tag()) {3701 const field_name = switch (struct_ty.tag()) {
3654 .@"struct" => struct_ty.structFields().keys()[extra.field_index],3702 .@"struct" => struct_ty.structFields().keys()[extra.field_index],
3655 .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[extra.field_index],3703 .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[extra.field_index],
...@@ -3657,8 +3705,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3657,8 +3705,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
3657 const tuple = struct_ty.tupleFields();3705 const tuple = struct_ty.tupleFields();
3658 if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none;3706 if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none;
36593707
3660 try buf.writer().print("field_{d}", .{extra.field_index});3708 field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{extra.field_index});
3661 break :blk buf.items;3709 break :blk field_name_buf;
3662 },3710 },
3663 else => unreachable,3711 else => unreachable,
3664 };3712 };
...@@ -4125,8 +4173,9 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4125,8 +4173,9 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
4125 const layout = union_ty.unionGetLayout(target);4173 const layout = union_ty.unionGetLayout(target);
4126 if (layout.tag_size == 0) return CValue.none;4174 if (layout.tag_size == 0) return CValue.none;
41274175
4176 try writer.writeByte('(');
4128 try f.writeCValue(writer, union_ptr);4177 try f.writeCValue(writer, union_ptr);
4129 try writer.writeAll("->tag = ");4178 try writer.writeAll(")->tag = ");
4130 try f.writeCValue(writer, new_tag);4179 try f.writeCValue(writer, new_tag);
4131 try writer.writeAll(";\n");4180 try writer.writeAll(";\n");
41324181
src/link/C.zig+32-27
...@@ -108,10 +108,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -108,10 +108,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
108 const typedefs = &gop.value_ptr.typedefs;108 const typedefs = &gop.value_ptr.typedefs;
109 const code = &gop.value_ptr.code;109 const code = &gop.value_ptr.code;
110 fwd_decl.shrinkRetainingCapacity(0);110 fwd_decl.shrinkRetainingCapacity(0);
111 {111 for (typedefs.values()) |typedef| {
112 for (typedefs.values()) |value| {112 module.gpa.free(typedef.rendered);
113 module.gpa.free(value.rendered);
114 }
115 }113 }
116 typedefs.clearRetainingCapacity();114 typedefs.clearRetainingCapacity();
117 code.shrinkRetainingCapacity(0);115 code.shrinkRetainingCapacity(0);
...@@ -139,14 +137,14 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes...@@ -139,14 +137,14 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
139137
140 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };138 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
141 defer {139 defer {
142 function.value_map.deinit();
143 function.blocks.deinit(module.gpa);140 function.blocks.deinit(module.gpa);
141 function.value_map.deinit();
144 function.object.code.deinit();142 function.object.code.deinit();
145 function.object.dg.fwd_decl.deinit();143 for (function.object.dg.typedefs.values()) |typedef| {
146 for (function.object.dg.typedefs.values()) |value| {144 module.gpa.free(typedef.rendered);
147 module.gpa.free(value.rendered);
148 }145 }
149 function.object.dg.typedefs.deinit();146 function.object.dg.typedefs.deinit();
147 function.object.dg.fwd_decl.deinit();
150 }148 }
151149
152 codegen.genFunc(&function) catch |err| switch (err) {150 codegen.genFunc(&function) catch |err| switch (err) {
...@@ -179,10 +177,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -179,10 +177,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
179 const typedefs = &gop.value_ptr.typedefs;177 const typedefs = &gop.value_ptr.typedefs;
180 const code = &gop.value_ptr.code;178 const code = &gop.value_ptr.code;
181 fwd_decl.shrinkRetainingCapacity(0);179 fwd_decl.shrinkRetainingCapacity(0);
182 {180 for (typedefs.values()) |value| {
183 for (typedefs.values()) |value| {181 module.gpa.free(value.rendered);
184 module.gpa.free(value.rendered);
185 }
186 }182 }
187 typedefs.clearRetainingCapacity();183 typedefs.clearRetainingCapacity();
188 code.shrinkRetainingCapacity(0);184 code.shrinkRetainingCapacity(0);
...@@ -206,11 +202,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -206,11 +202,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
206 object.indent_writer = .{ .underlying_writer = object.code.writer() };202 object.indent_writer = .{ .underlying_writer = object.code.writer() };
207 defer {203 defer {
208 object.code.deinit();204 object.code.deinit();
209 object.dg.fwd_decl.deinit();205 for (object.dg.typedefs.values()) |typedef| {
210 for (object.dg.typedefs.values()) |value| {206 module.gpa.free(typedef.rendered);
211 module.gpa.free(value.rendered);
212 }207 }
213 object.dg.typedefs.deinit();208 object.dg.typedefs.deinit();
209 object.dg.fwd_decl.deinit();
214 }210 }
215211
216 codegen.genDecl(&object) catch |err| switch (err) {212 codegen.genDecl(&object) catch |err| switch (err) {
...@@ -307,10 +303,10 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)...@@ -307,10 +303,10 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node)
307}303}
308304
309const Flush = struct {305const Flush = struct {
306 err_decls: DeclBlock = .{},
310 remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},307 remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{},
311 typedefs: Typedefs = .{},308 typedefs: Typedefs = .{},
312 typedef_buf: std.ArrayListUnmanaged(u8) = .{},309 typedef_buf: std.ArrayListUnmanaged(u8) = .{},
313 err_buf: std.ArrayListUnmanaged(u8) = .{},
314 /// We collect a list of buffers to write, and write them all at once with pwritev 😎310 /// We collect a list of buffers to write, and write them all at once with pwritev 😎
315 all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{},311 all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{},
316 /// Keeps track of the total bytes of `all_buffers`.312 /// Keeps track of the total bytes of `all_buffers`.
...@@ -332,10 +328,10 @@ const Flush = struct {...@@ -332,10 +328,10 @@ const Flush = struct {
332328
333 fn deinit(f: *Flush, gpa: Allocator) void {329 fn deinit(f: *Flush, gpa: Allocator) void {
334 f.all_buffers.deinit(gpa);330 f.all_buffers.deinit(gpa);
335 f.err_buf.deinit(gpa);
336 f.typedef_buf.deinit(gpa);331 f.typedef_buf.deinit(gpa);
337 f.typedefs.deinit(gpa);332 f.typedefs.deinit(gpa);
338 f.remaining_decls.deinit(gpa);333 f.remaining_decls.deinit(gpa);
334 f.err_decls.deinit(gpa);
339 }335 }
340};336};
341337
...@@ -365,6 +361,10 @@ fn flushTypedefs(self: *C, f: *Flush, typedefs: codegen.TypedefMap.Unmanaged) Fl...@@ -365,6 +361,10 @@ fn flushTypedefs(self: *C, f: *Flush, typedefs: codegen.TypedefMap.Unmanaged) Fl
365fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {361fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {
366 const module = self.base.options.module.?;362 const module = self.base.options.module.?;
367363
364 const fwd_decl = &f.err_decls.fwd_decl;
365 const typedefs = &f.err_decls.typedefs;
366 const code = &f.err_decls.code;
367
368 var object = codegen.Object{368 var object = codegen.Object{
369 .dg = .{369 .dg = .{
370 .gpa = module.gpa,370 .gpa = module.gpa,
...@@ -372,20 +372,21 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {...@@ -372,20 +372,21 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {
372 .error_msg = null,372 .error_msg = null,
373 .decl_index = undefined,373 .decl_index = undefined,
374 .decl = undefined,374 .decl = undefined,
375 .fwd_decl = undefined,375 .fwd_decl = fwd_decl.toManaged(module.gpa),
376 .typedefs = codegen.TypedefMap.initContext(module.gpa, .{ .mod = module }),376 .typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }),
377 .typedefs_arena = self.arena.allocator(),377 .typedefs_arena = self.arena.allocator(),
378 },378 },
379 .code = f.err_buf.toManaged(module.gpa),379 .code = code.toManaged(module.gpa),
380 .indent_writer = undefined, // set later so we can get a pointer to object.code380 .indent_writer = undefined, // set later so we can get a pointer to object.code
381 };381 };
382 object.indent_writer = .{ .underlying_writer = object.code.writer() };382 object.indent_writer = .{ .underlying_writer = object.code.writer() };
383 defer {383 defer {
384 f.err_buf = object.code.moveToUnmanaged();384 object.code.deinit();
385 for (object.dg.typedefs.values()) |value| {385 for (object.dg.typedefs.values()) |typedef| {
386 module.gpa.free(value.rendered);386 module.gpa.free(typedef.rendered);
387 }387 }
388 object.dg.typedefs.deinit();388 object.dg.typedefs.deinit();
389 object.dg.fwd_decl.deinit();
389 }390 }
390391
391 codegen.genErrDecls(&object) catch |err| switch (err) {392 codegen.genErrDecls(&object) catch |err| switch (err) {
...@@ -393,11 +394,15 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {...@@ -393,11 +394,15 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void {
393 else => |e| return e,394 else => |e| return e,
394 };395 };
395396
396 const gpa = self.base.allocator;397 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
398 typedefs.* = object.dg.typedefs.unmanaged;
399 object.dg.typedefs.unmanaged = .{};
400 code.* = object.code.moveToUnmanaged();
397401
398 try self.flushTypedefs(f, object.dg.typedefs.unmanaged);402 try self.flushTypedefs(f, typedefs.*);
399 try f.all_buffers.ensureUnusedCapacity(gpa, 1);403 try f.all_buffers.ensureUnusedCapacity(self.base.allocator, 1);
400 f.appendBufAssumeCapacity(object.code.items);404 f.appendBufAssumeCapacity(fwd_decl.items);
405 f.appendBufAssumeCapacity(code.items);
401}406}
402407
403/// Assumes `decl` was in the `remaining_decls` set, and has already been removed.408/// Assumes `decl` was in the `remaining_decls` set, and has already been removed.
test/behavior/align.zig-1
...@@ -476,7 +476,6 @@ test "read 128-bit field from default aligned struct in global memory" {...@@ -476,7 +476,6 @@ test "read 128-bit field from default aligned struct in global memory" {
476}476}
477477
478test "struct field explicit alignment" {478test "struct field explicit alignment" {
479 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
480 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;479 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
481 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;480 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
482 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;481 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
test/behavior/atomics.zig-1
...@@ -33,7 +33,6 @@ fn testCmpxchg() !void {...@@ -33,7 +33,6 @@ fn testCmpxchg() !void {
33}33}
3434
35test "fence" {35test "fence" {
36 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO36 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
38 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO37 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
39 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO38 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/basic.zig-1
...@@ -590,7 +590,6 @@ test "equality compare fn ptrs" {...@@ -590,7 +590,6 @@ test "equality compare fn ptrs" {
590590
591test "self reference through fn ptr field" {591test "self reference through fn ptr field" {
592 if (builtin.zig_backend == .stage1) return error.SkipZigTest;592 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
593 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
594593
595 const S = struct {594 const S = struct {
596 const A = struct {595 const A = struct {
test/behavior/bugs/1310.zig-1
...@@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {...@@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 {
2424
25test "fixed" {25test "fixed" {
26 if (builtin.zig_backend == .stage1) return error.SkipZigTest;26 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
27 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
28 try expect(agent_callback(undefined, undefined) == 11);27 try expect(agent_callback(undefined, undefined) == 11);
29}28}
test/behavior/bugs/1500.zig-1
...@@ -6,7 +6,6 @@ const A = struct {...@@ -6,7 +6,6 @@ const A = struct {
6const B = *const fn (A) void;6const B = *const fn (A) void;
77
8test "allow these dependencies" {8test "allow these dependencies" {
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
10 var a: A = undefined;9 var a: A = undefined;
11 var b: B = undefined;10 var b: B = undefined;
12 if (false) {11 if (false) {
test/behavior/bugs/2006.zig-1
...@@ -6,7 +6,6 @@ const S = struct {...@@ -6,7 +6,6 @@ const S = struct {
6 p: *S,6 p: *S,
7};7};
8test "bug 2006" {8test "bug 2006" {
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
10 var a: S = undefined;9 var a: S = undefined;
11 a = S{ .p = undefined };10 a = S{ .p = undefined };
12 try expect(@sizeOf(S) != 0);11 try expect(@sizeOf(S) != 0);
test/behavior/cast.zig-4
...@@ -410,7 +410,6 @@ fn testCastIntToErr(err: anyerror) !void {...@@ -410,7 +410,6 @@ fn testCastIntToErr(err: anyerror) !void {
410410
411test "peer resolve array and const slice" {411test "peer resolve array and const slice" {
412 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;412 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
413 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
414 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO413 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
415 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO414 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
416415
...@@ -546,7 +545,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {...@@ -546,7 +545,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
546545
547test "single-item pointer of array to slice to unknown length pointer" {546test "single-item pointer of array to slice to unknown length pointer" {
548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;547 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
549 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
550548
551 try testCastPtrOfArrayToSliceAndPtr();549 try testCastPtrOfArrayToSliceAndPtr();
552 comptime try testCastPtrOfArrayToSliceAndPtr();550 comptime try testCastPtrOfArrayToSliceAndPtr();
...@@ -575,7 +573,6 @@ fn testCastPtrOfArrayToSliceAndPtr() !void {...@@ -575,7 +573,6 @@ fn testCastPtrOfArrayToSliceAndPtr() !void {
575573
576test "cast *[1][*]const u8 to [*]const ?[*]const u8" {574test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
577 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;575 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
578 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
579 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO576 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
580577
581 const window_name = [1][*]const u8{"window name"};578 const window_name = [1][*]const u8{"window name"};
...@@ -1235,7 +1232,6 @@ test "cast from array reference to fn: runtime fn ptr" {...@@ -1235,7 +1232,6 @@ test "cast from array reference to fn: runtime fn ptr" {
12351232
1236test "*const [N]null u8 to ?[]const u8" {1233test "*const [N]null u8 to ?[]const u8" {
1237 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1234 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1238 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1239 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1235 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12401236
1241 const S = struct {1237 const S = struct {
test/behavior/floatop.zig-2
...@@ -21,7 +21,6 @@ fn epsForType(comptime T: type) T {...@@ -21,7 +21,6 @@ fn epsForType(comptime T: type) T {
2121
22test "floating point comparisons" {22test "floating point comparisons" {
23 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
2625
27 try testFloatComparisons();26 try testFloatComparisons();
...@@ -91,7 +90,6 @@ fn testDifferentSizedFloatComparisons() !void {...@@ -91,7 +90,6 @@ fn testDifferentSizedFloatComparisons() !void {
9190
92test "negative f128 floatToInt at compile-time" {91test "negative f128 floatToInt at compile-time" {
93 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO92 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
94 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
95 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO93 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
96 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO94 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9795
test/behavior/generics.zig-1
...@@ -204,7 +204,6 @@ fn foo2(arg: anytype) bool {...@@ -204,7 +204,6 @@ fn foo2(arg: anytype) bool {
204}204}
205205
206test "generic struct" {206test "generic struct" {
207 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
208 var a1 = GenNode(i32){207 var a1 = GenNode(i32){
209 .value = 13,208 .value = 13,
210 .next = null,209 .next = null,
test/behavior/math.zig-3
...@@ -603,7 +603,6 @@ fn should_not_be_zero(x: f128) !void {...@@ -603,7 +603,6 @@ fn should_not_be_zero(x: f128) !void {
603}603}
604604
605test "128-bit multiplication" {605test "128-bit multiplication" {
606 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
607 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO606 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
608 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO607 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
609 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO608 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -650,8 +649,6 @@ test "@addWithOverflow" {...@@ -650,8 +649,6 @@ test "@addWithOverflow" {
650}649}
651650
652test "small int addition" {651test "small int addition" {
653 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
654
655 var x: u2 = 0;652 var x: u2 = 0;
656 try expect(x == 0);653 try expect(x == 0);
657654
test/behavior/maximum_minimum.zig-2
...@@ -6,7 +6,6 @@ const expectEqual = std.testing.expectEqual;...@@ -6,7 +6,6 @@ const expectEqual = std.testing.expectEqual;
66
7test "@max" {7test "@max" {
8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1211
...@@ -55,7 +54,6 @@ test "@min" {...@@ -55,7 +54,6 @@ test "@min" {
55 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO56 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
5957
60 const S = struct {58 const S = struct {
61 fn doTheTest() !void {59 fn doTheTest() !void {
test/behavior/muladd.zig-1
...@@ -2,7 +2,6 @@ const builtin = @import("builtin");...@@ -2,7 +2,6 @@ const builtin = @import("builtin");
2const expect = @import("std").testing.expect;2const expect = @import("std").testing.expect;
33
4test "@mulAdd" {4test "@mulAdd" {
5 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO5 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/packed-struct.zig-1
...@@ -293,7 +293,6 @@ test "regular in irregular packed struct" {...@@ -293,7 +293,6 @@ test "regular in irregular packed struct" {
293test "byte-aligned field pointer offsets" {293test "byte-aligned field pointer offsets" {
294 if (builtin.zig_backend == .stage1) return error.SkipZigTest;294 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
295 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;295 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
296 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
297 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;296 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
298 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;297 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
299 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;298 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
test/behavior/saturating_arithmetic.zig-1
...@@ -239,7 +239,6 @@ test "saturating shl uses the LHS type" {...@@ -239,7 +239,6 @@ test "saturating shl uses the LHS type" {
239 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO239 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
242 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
243242
244 const lhs_const: u8 = 1;243 const lhs_const: u8 = 1;
245 var lhs_var: u8 = 1;244 var lhs_var: u8 = 1;
test/behavior/struct.zig-2
...@@ -284,7 +284,6 @@ const Val = struct {...@@ -284,7 +284,6 @@ const Val = struct {
284284
285test "struct point to self" {285test "struct point to self" {
286 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;286 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
287 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
288 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
289288
290 var root: Node = undefined;289 var root: Node = undefined;
...@@ -393,7 +392,6 @@ const APackedStruct = packed struct {...@@ -393,7 +392,6 @@ const APackedStruct = packed struct {
393test "packed struct" {392test "packed struct" {
394 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;393 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
395 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO394 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
396 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO395 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
398 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO396 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO397 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/struct_contains_null_ptr_itself.zig-1
...@@ -5,7 +5,6 @@ const builtin = @import("builtin");...@@ -5,7 +5,6 @@ const builtin = @import("builtin");
5test "struct contains null pointer which contains original struct" {5test "struct contains null pointer which contains original struct" {
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
9 var x: ?*NodeLineComment = null;8 var x: ?*NodeLineComment = null;
10 try expect(x == null);9 try expect(x == null);
11}10}
test/behavior/switch_prong_implicit_cast.zig-1
...@@ -18,7 +18,6 @@ test "switch prong implicit cast" {...@@ -18,7 +18,6 @@ test "switch prong implicit cast" {
18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
20 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;20 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
21 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
22 const result = switch (foo(2) catch unreachable) {21 const result = switch (foo(2) catch unreachable) {
23 FormValue.One => false,22 FormValue.One => false,
24 FormValue.Two => |x| x,23 FormValue.Two => |x| x,
test/behavior/union.zig-3
...@@ -1186,7 +1186,6 @@ test "comptime equality of extern unions with same tag" {...@@ -1186,7 +1186,6 @@ test "comptime equality of extern unions with same tag" {
1186}1186}
11871187
1188test "union tag is set when initiated as a temporary value at runtime" {1188test "union tag is set when initiated as a temporary value at runtime" {
1189 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1190 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1189 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1191 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1190 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11921191
...@@ -1350,7 +1349,6 @@ test "@unionInit uses tag value instead of field index" {...@@ -1350,7 +1349,6 @@ test "@unionInit uses tag value instead of field index" {
1350}1349}
13511350
1352test "union field ptr - zero sized payload" {1351test "union field ptr - zero sized payload" {
1353 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1354 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1352 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1355 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13561354
...@@ -1364,7 +1362,6 @@ test "union field ptr - zero sized payload" {...@@ -1364,7 +1362,6 @@ test "union field ptr - zero sized payload" {
1364}1362}
13651363
1366test "union field ptr - zero sized field" {1364test "union field ptr - zero sized field" {
1367 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1368 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1365 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1369 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1366 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13701367
test/behavior/vector.zig-1
...@@ -811,7 +811,6 @@ test "vector reduce operation" {...@@ -811,7 +811,6 @@ test "vector reduce operation" {
811test "vector @reduce comptime" {811test "vector @reduce comptime" {
812 if (builtin.zig_backend == .stage1) return error.SkipZigTest;812 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
813 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO813 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
814 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
815 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO814 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
816 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO815 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
817 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO816 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO