authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-23 18:47:09-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-02-23 20:30:59-05:00
log9d24d0354f83a7cd706726d47a2dc9ac092304e7
tree659aa0a1079d15b3e59e031d57cfd6e22e7a6c9e
parenta0d7fd162b7568c0291ebcfc561a2852c7077e15

CBE: fix MSVC diagnostics generated by the behavior tests

After this, the last MSVC warnings are in behavior/bugs/529.zig: behavior.c(37971): warning C4133: 'function': incompatible types - from 'A__8479 *' to 'A__8474 *' behavior.c(37974): warning C4133: 'function': incompatible types - from 'A__8480 *' to 'A__8474 *'

2 files changed, 106 insertions(+), 98 deletions(-)

lib/zig.h+36-28
...@@ -1076,7 +1076,7 @@ static inline void zig_vmulo_i16(uint8_t *ov, int16_t *res, int n,...@@ -1076,7 +1076,7 @@ static inline void zig_vmulo_i16(uint8_t *ov, int16_t *res, int n,
1076\1076\
1077 static inline int##w##_t zig_shls_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \1077 static inline int##w##_t zig_shls_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1078 int##w##_t res; \1078 int##w##_t res; \
1079 if ((uint##w##_t)rhs < (uint##w##_t)bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \1079 if ((uint##w##_t)rhs < (uint##w##_t)bits && !zig_shlo_i##w(&res, lhs, (uint8_t)rhs, bits)) return res; \
1080 return lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \1080 return lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1081 } \1081 } \
1082\1082\
...@@ -2410,39 +2410,47 @@ zig_msvc_atomics(i64, int64_t, 64)...@@ -2410,39 +2410,47 @@ zig_msvc_atomics(i64, int64_t, 64)
24102410
2411#define zig_msvc_flt_atomics(Type, ReprType, suffix) \2411#define zig_msvc_flt_atomics(Type, ReprType, suffix) \
2412 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \2412 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \
2413 ReprType comparand = *((ReprType*)expected); \2413 ReprType exchange; \
2414 ReprType initial = _InterlockedCompareExchange##suffix((ReprType volatile*)obj, *((ReprType*)&desired), comparand); \2414 ReprType comparand; \
2415 bool exchanged = initial == comparand; \2415 ReprType initial; \
2416 if (!exchanged) { \2416 bool success; \
2417 *expected = *((zig_##Type*)&initial); \2417 memcpy(&comparand, expected, sizeof(comparand)); \
2418 } \2418 memcpy(&exchange, &desired, sizeof(exchange)); \
2419 return exchanged; \2419 initial = _InterlockedCompareExchange##suffix((ReprType volatile*)obj, exchange, comparand); \
2420 success = initial == comparand; \
2421 if (!success) memcpy(expected, &initial, sizeof(*expected)); \
2422 return success; \
2420 } \2423 } \
2421 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \2424 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \
2422 ReprType initial = _InterlockedExchange##suffix((ReprType volatile*)obj, *((ReprType*)&value)); \2425 ReprType repr; \
2423 return *((zig_##Type*)&initial); \2426 ReprType initial; \
2427 zig_##Type result; \
2428 memcpy(&repr, &value, sizeof(repr)); \
2429 initial = _InterlockedExchange##suffix((ReprType volatile*)obj, repr); \
2430 memcpy(&result, &initial, sizeof(result)); \
2431 return result; \
2424 } \2432 } \
2425 static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \2433 static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \
2426 bool success = false; \2434 ReprType repr; \
2427 ReprType new; \2435 zig_##Type expected; \
2428 zig_##Type prev; \2436 zig_##Type desired; \
2429 while (!success) { \2437 repr = *(ReprType volatile*)obj; \
2430 prev = *obj; \2438 memcpy(&expected, &repr, sizeof(expected)); \
2431 new = prev + value; \2439 do { \
2432 success = zig_msvc_cmpxchg_##Type(obj, &prev, *((ReprType*)&new)); \2440 desired = expected + value; \
2433 } \2441 } while (!zig_msvc_cmpxchg_##Type(obj, &expected, desired)); \
2434 return prev; \2442 return expected; \
2435 } \2443 } \
2436 static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \2444 static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \
2437 bool success = false; \2445 ReprType repr; \
2438 ReprType new; \2446 zig_##Type expected; \
2439 zig_##Type prev; \2447 zig_##Type desired; \
2440 while (!success) { \2448 repr = *(ReprType volatile*)obj; \
2441 prev = *obj; \2449 memcpy(&expected, &repr, sizeof(expected)); \
2442 new = prev - value; \2450 do { \
2443 success = zig_msvc_cmpxchg_##Type(obj, &prev, *((ReprType*)&new)); \2451 desired = expected - value; \
2444 } \2452 } while (!zig_msvc_cmpxchg_##Type(obj, &expected, desired)); \
2445 return prev; \2453 return expected; \
2446 }2454 }
24472455
2448zig_msvc_flt_atomics(f32, uint32_t, )2456zig_msvc_flt_atomics(f32, uint32_t, )
src/codegen/c.zig+70-70
...@@ -882,14 +882,14 @@ pub const DeclGen = struct {...@@ -882,14 +882,14 @@ pub const DeclGen = struct {
882 var literal = stringLiteral(writer);882 var literal = stringLiteral(writer);
883 try literal.start();883 try literal.start();
884 const c_len = ty.arrayLenIncludingSentinel();884 const c_len = ty.arrayLenIncludingSentinel();
885 var index: usize = 0;885 var index: u64 = 0;
886 while (index < c_len) : (index += 1)886 while (index < c_len) : (index += 1)
887 try literal.writeChar(0xaa);887 try literal.writeChar(0xaa);
888 return literal.end();888 return literal.end();
889 } else {889 } else {
890 try writer.writeByte('{');890 try writer.writeByte('{');
891 const c_len = ty.arrayLenIncludingSentinel();891 const c_len = ty.arrayLenIncludingSentinel();
892 var index: usize = 0;892 var index: u64 = 0;
893 while (index < c_len) : (index += 1) {893 while (index < c_len) : (index += 1) {
894 if (index > 0) try writer.writeAll(", ");894 if (index > 0) try writer.writeAll(", ");
895 try dg.renderValue(writer, ty.childType(), val, initializer_type);895 try dg.renderValue(writer, ty.childType(), val, initializer_type);
...@@ -1089,8 +1089,8 @@ pub const DeclGen = struct {...@@ -1089,8 +1089,8 @@ pub const DeclGen = struct {
1089 // First try specific tag representations for more efficiency.1089 // First try specific tag representations for more efficiency.
1090 switch (val.tag()) {1090 switch (val.tag()) {
1091 .undef, .empty_struct_value, .empty_array => {1091 .undef, .empty_struct_value, .empty_array => {
1092 try writer.writeByte('{');
1093 const ai = ty.arrayInfo();1092 const ai = ty.arrayInfo();
1093 try writer.writeByte('{');
1094 if (ai.sentinel) |s| {1094 if (ai.sentinel) |s| {
1095 try dg.renderValue(writer, ai.elem_type, s, initializer_type);1095 try dg.renderValue(writer, ai.elem_type, s, initializer_type);
1096 } else {1096 } else {
...@@ -1098,13 +1098,19 @@ pub const DeclGen = struct {...@@ -1098,13 +1098,19 @@ pub const DeclGen = struct {
1098 }1098 }
1099 try writer.writeByte('}');1099 try writer.writeByte('}');
1100 },1100 },
1101 .bytes => {1101 .bytes, .str_lit => |t| {
1102 try writer.print("{s}", .{fmtStringLiteral(val.castTag(.bytes).?.data)});1102 const bytes = switch (t) {
1103 },1103 .bytes => val.castTag(.bytes).?.data,
1104 .str_lit => {1104 .str_lit => bytes: {
1105 const str_lit = val.castTag(.str_lit).?.data;1105 const str_lit = val.castTag(.str_lit).?.data;
1106 const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];1106 break :bytes dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
1107 try writer.print("{s}", .{fmtStringLiteral(bytes)});1107 },
1108 else => unreachable,
1109 };
1110 const sentinel = if (ty.sentinel()) |sentinel| @intCast(u8, sentinel.toUnsignedInt(target)) else null;
1111 try writer.print("{s}", .{
1112 fmtStringLiteral(bytes[0..@intCast(usize, ty.arrayLen())], sentinel),
1113 });
1108 },1114 },
1109 else => {1115 else => {
1110 // Fall back to generic implementation.1116 // Fall back to generic implementation.
...@@ -1128,7 +1134,7 @@ pub const DeclGen = struct {...@@ -1128,7 +1134,7 @@ pub const DeclGen = struct {
1128 }1134 }
1129 if (ai.sentinel) |s| {1135 if (ai.sentinel) |s| {
1130 const s_u8 = @intCast(u8, s.toUnsignedInt(target));1136 const s_u8 = @intCast(u8, s.toUnsignedInt(target));
1131 try literal.writeChar(s_u8);1137 if (s_u8 != 0) try literal.writeChar(s_u8);
1132 }1138 }
1133 try literal.end();1139 try literal.end();
1134 } else {1140 } else {
...@@ -1638,6 +1644,11 @@ pub const DeclGen = struct {...@@ -1638,6 +1644,11 @@ pub const DeclGen = struct {
1638 try context.writeValue(dg, w, src_ty, location);1644 try context.writeValue(dg, w, src_ty, location);
1639 } else if (dest_bits <= 64 and src_bits > 64) {1645 } else if (dest_bits <= 64 and src_bits > 64) {
1640 assert(!src_is_ptr);1646 assert(!src_is_ptr);
1647 if (dest_bits < 64) {
1648 try w.writeByte('(');
1649 try dg.renderType(w, dest_ty);
1650 try w.writeByte(')');
1651 }
1641 try w.writeAll("zig_lo_");1652 try w.writeAll("zig_lo_");
1642 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);1653 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
1643 try w.writeByte('(');1654 try w.writeByte('(');
...@@ -2380,9 +2391,7 @@ pub fn genTypeDecl(...@@ -2380,9 +2391,7 @@ pub fn genTypeDecl(
23802391
2381pub fn genGlobalAsm(mod: *Module, writer: anytype) !void {2392pub fn genGlobalAsm(mod: *Module, writer: anytype) !void {
2382 var it = mod.global_assembly.valueIterator();2393 var it = mod.global_assembly.valueIterator();
2383 while (it.next()) |asm_source| {2394 while (it.next()) |asm_source| try writer.print("__asm({s});\n", .{fmtStringLiteral(asm_source.*, null)});
2384 try writer.print("__asm({s});\n", .{fmtStringLiteral(asm_source.*)});
2385 }
2386}2395}
23872396
2388pub fn genErrDecls(o: *Object) !void {2397pub fn genErrDecls(o: *Object) !void {
...@@ -2400,22 +2409,20 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2400,22 +2409,20 @@ pub fn genErrDecls(o: *Object) !void {
2400 o.indent_writer.popIndent();2409 o.indent_writer.popIndent();
2401 try writer.writeAll("};\n");2410 try writer.writeAll("};\n");
24022411
2403 const name_prefix = "zig_errorName";2412 const array_identifier = "zig_errorName";
2404 const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + "_".len + max_name_len + 1);2413 const name_prefix = array_identifier ++ "_";
2414 const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + max_name_len);
2405 defer o.dg.gpa.free(name_buf);2415 defer o.dg.gpa.free(name_buf);
24062416
2407 std.mem.copy(u8, name_buf, name_prefix ++ "_");2417 std.mem.copy(u8, name_buf, name_prefix);
2408 for (o.dg.module.error_name_list.items) |name| {2418 for (o.dg.module.error_name_list.items) |name| {
2409 std.mem.copy(u8, name_buf[name_prefix.len + "_".len ..], name);2419 std.mem.copy(u8, name_buf[name_prefix.len..], name);
2410 name_buf[name_prefix.len + "_".len + name.len] = 0;2420 const identifier = name_buf[0 .. name_prefix.len + name.len];
2411
2412 const identifier = name_buf[0 .. name_prefix.len + "_".len + name.len :0];
2413 const name_z = identifier[name_prefix.len + "_".len ..];
24142421
2415 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };2422 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };
2416 const name_ty = Type.initPayload(&name_ty_pl.base);2423 const name_ty = Type.initPayload(&name_ty_pl.base);
24172424
2418 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_z };2425 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };
2419 const name_val = Value.initPayload(&name_pl.base);2426 const name_val = Value.initPayload(&name_pl.base);
24202427
2421 try writer.writeAll("static ");2428 try writer.writeAll("static ");
...@@ -2432,7 +2439,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2432,7 +2439,7 @@ pub fn genErrDecls(o: *Object) !void {
2432 const name_array_ty = Type.initPayload(&name_array_ty_pl.base);2439 const name_array_ty = Type.initPayload(&name_array_ty_pl.base);
24332440
2434 try writer.writeAll("static ");2441 try writer.writeAll("static ");
2435 try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = name_prefix }, Const, 0, .complete);2442 try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, 0, .complete);
2436 try writer.writeAll(" = {");2443 try writer.writeAll(" = {");
2437 for (o.dg.module.error_name_list.items, 0..) |name, value| {2444 for (o.dg.module.error_name_list.items, 0..) |name, value| {
2438 if (value != 0) try writer.writeByte(',');2445 if (value != 0) try writer.writeByte(',');
...@@ -2440,7 +2447,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2440,7 +2447,7 @@ pub fn genErrDecls(o: *Object) !void {
2440 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };2447 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
2441 const len_val = Value.initPayload(&len_pl.base);2448 const len_val = Value.initPayload(&len_pl.base);
24422449
2443 try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{2450 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
2444 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val),2451 fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val),
2445 });2452 });
2446 }2453 }
...@@ -2457,8 +2464,8 @@ fn genExports(o: *Object) !void {...@@ -2457,8 +2464,8 @@ fn genExports(o: *Object) !void {
2457 try fwd_decl_writer.writeAll("zig_export(");2464 try fwd_decl_writer.writeAll("zig_export(");
2458 try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) });2465 try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) });
2459 try fwd_decl_writer.print(", {s}, {s});\n", .{2466 try fwd_decl_writer.print(", {s}, {s});\n", .{
2460 fmtStringLiteral(exports.items[0].options.name),2467 fmtStringLiteral(exports.items[0].options.name, null),
2461 fmtStringLiteral(@"export".options.name),2468 fmtStringLiteral(@"export".options.name, null),
2462 });2469 });
2463 }2470 }
2464 }2471 }
...@@ -2483,10 +2490,6 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2483,10 +2490,6 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2483 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, 0, .complete);2490 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, 0, .complete);
2484 try w.writeAll(") {\n switch (tag) {\n");2491 try w.writeAll(") {\n switch (tag) {\n");
2485 for (enum_ty.enumFields().keys(), 0..) |name, index| {2492 for (enum_ty.enumFields().keys(), 0..) |name, index| {
2486 const name_z = try o.dg.gpa.dupeZ(u8, name);
2487 defer o.dg.gpa.free(name_z);
2488 const name_bytes = name_z[0 .. name_z.len + 1];
2489
2490 var tag_pl: Value.Payload.U32 = .{2493 var tag_pl: Value.Payload.U32 = .{
2491 .base = .{ .tag = .enum_field_index },2494 .base = .{ .tag = .enum_field_index },
2492 .data = @intCast(u32, index),2495 .data = @intCast(u32, index),
...@@ -2499,7 +2502,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2499,7 +2502,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2499 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };2502 var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len };
2500 const name_ty = Type.initPayload(&name_ty_pl.base);2503 const name_ty = Type.initPayload(&name_ty_pl.base);
25012504
2502 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_bytes };2505 var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name };
2503 const name_val = Value.initPayload(&name_pl.base);2506 const name_val = Value.initPayload(&name_pl.base);
25042507
2505 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };2508 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
...@@ -3459,15 +3462,17 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3459,15 +3462,17 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3459 try f.writeCValue(writer, local, .Other);3462 try f.writeCValue(writer, local, .Other);
3460 try writer.writeAll(" = ");3463 try writer.writeAll(" = ");
34613464
3465 if (dest_c_bits < 64) {
3466 try writer.writeByte('(');
3467 try f.renderType(writer, inst_ty);
3468 try writer.writeByte(')');
3469 }
3470
3462 const needs_lo = operand_int_info.bits > 64 and dest_bits <= 64;3471 const needs_lo = operand_int_info.bits > 64 and dest_bits <= 64;
3463 if (needs_lo) {3472 if (needs_lo) {
3464 try writer.writeAll("zig_lo_");3473 try writer.writeAll("zig_lo_");
3465 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);3474 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
3466 try writer.writeByte('(');3475 try writer.writeByte('(');
3467 } else if (dest_c_bits <= 64) {
3468 try writer.writeByte('(');
3469 try f.renderType(writer, inst_ty);
3470 try writer.writeByte(')');
3471 }3476 }
34723477
3473 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {3478 if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) {
...@@ -4228,8 +4233,9 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4228,8 +4233,9 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
42284233
4229 try genBodyInner(f, body);4234 try genBodyInner(f, body);
4230 try f.object.indent_writer.insertNewline();4235 try f.object.indent_writer.insertNewline();
4236 // label might be unused, add a dummy goto
4231 // label must be followed by an expression, add an empty one.4237 // label must be followed by an expression, add an empty one.
4232 try writer.print("zig_block_{d}:;\n", .{block_id});4238 try writer.print("goto zig_block_{d};\nzig_block_{d}: (void)0;\n", .{ block_id, block_id });
4233 return result;4239 return result;
4234}4240}
42354241
...@@ -4608,8 +4614,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4608,8 +4614,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4608 const last_case_i = switch_br.data.cases_len - @boolToInt(switch_br.data.else_body_len == 0);4614 const last_case_i = switch_br.data.cases_len - @boolToInt(switch_br.data.else_body_len == 0);
46094615
4610 var extra_index: usize = switch_br.end;4616 var extra_index: usize = switch_br.end;
4611 var case_i: u32 = 0;4617 for (0..switch_br.data.cases_len) |case_i| {
4612 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
4613 const case = f.air.extraData(Air.SwitchBr.Case, extra_index);4618 const case = f.air.extraData(Air.SwitchBr.Case, extra_index);
4614 const items = @ptrCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]);4619 const items = @ptrCast([]const Air.Inst.Ref, f.air.extra[case.end..][0..case.data.items_len]);
4615 const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len];4620 const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len];
...@@ -4789,14 +4794,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4789,14 +4794,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4789 try writer.writeAll(";\n");4794 try writer.writeAll(";\n");
4790 }4795 }
4791 }4796 }
4792 {4797 for (0..clobbers_len) |_| {
4793 var clobber_i: u32 = 0;4798 const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);
4794 while (clobber_i < clobbers_len) : (clobber_i += 1) {4799 // This equation accounts for the fact that even if we have exactly 4 bytes
4795 const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);4800 // for the string, we still use the next u32 for the null terminator.
4796 // This equation accounts for the fact that even if we have exactly 4 bytes4801 extra_i += clobber.len / 4 + 1;
4797 // for the string, we still use the next u32 for the null terminator.
4798 extra_i += clobber.len / 4 + 1;
4799 }
4800 }4802 }
48014803
4802 {4804 {
...@@ -4851,7 +4853,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4851,7 +4853,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
48514853
4852 try writer.writeAll("__asm");4854 try writer.writeAll("__asm");
4853 if (is_volatile) try writer.writeAll(" volatile");4855 if (is_volatile) try writer.writeAll(" volatile");
4854 try writer.print("({s}", .{fmtStringLiteral(fixed_asm_source[0..dst_i])});4856 try writer.print("({s}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)});
4855 }4857 }
48564858
4857 extra_i = constraints_extra_begin;4859 extra_i = constraints_extra_begin;
...@@ -4869,7 +4871,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4869,7 +4871,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4869 try writer.writeByte(' ');4871 try writer.writeByte(' ');
4870 if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});4872 if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});
4871 const is_reg = constraint[1] == '{';4873 const is_reg = constraint[1] == '{';
4872 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint)});4874 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});
4873 if (is_reg) {4875 if (is_reg) {
4874 try f.writeCValue(writer, .{ .local = locals_index }, .Other);4876 try f.writeCValue(writer, .{ .local = locals_index }, .Other);
4875 locals_index += 1;4877 locals_index += 1;
...@@ -4895,7 +4897,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4895,7 +4897,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
48954897
4896 const is_reg = constraint[0] == '{';4898 const is_reg = constraint[0] == '{';
4897 const input_val = try f.resolveInst(input);4899 const input_val = try f.resolveInst(input);
4898 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint)});4900 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
4899 try f.writeCValue(writer, if (asmInputNeedsLocal(constraint, input_val)) local: {4901 try f.writeCValue(writer, if (asmInputNeedsLocal(constraint, input_val)) local: {
4900 const input_local = CValue{ .local = locals_index };4902 const input_local = CValue{ .local = locals_index };
4901 locals_index += 1;4903 locals_index += 1;
...@@ -4904,19 +4906,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4904,19 +4906,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4904 try writer.writeByte(')');4906 try writer.writeByte(')');
4905 }4907 }
4906 try writer.writeByte(':');4908 try writer.writeByte(':');
4907 {4909 for (0..clobbers_len) |clobber_i| {
4908 var clobber_i: u32 = 0;4910 const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);
4909 while (clobber_i < clobbers_len) : (clobber_i += 1) {4911 // This equation accounts for the fact that even if we have exactly 4 bytes
4910 const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);4912 // for the string, we still use the next u32 for the null terminator.
4911 // This equation accounts for the fact that even if we have exactly 4 bytes4913 extra_i += clobber.len / 4 + 1;
4912 // for the string, we still use the next u32 for the null terminator.
4913 extra_i += clobber.len / 4 + 1;
49144914
4915 if (clobber.len == 0) continue;4915 if (clobber.len == 0) continue;
49164916
4917 if (clobber_i > 0) try writer.writeByte(',');4917 if (clobber_i > 0) try writer.writeByte(',');
4918 try writer.print(" {s}", .{fmtStringLiteral(clobber)});4918 try writer.print(" {s}", .{fmtStringLiteral(clobber, null)});
4919 }
4920 }4919 }
4921 try writer.writeAll(");\n");4920 try writer.writeAll(");\n");
49224921
...@@ -5340,8 +5339,9 @@ fn fieldPtr(...@@ -5340,8 +5339,9 @@ fn fieldPtr(
5340 try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});5339 try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)});
5341 },5340 },
5342 .end => {5341 .end => {
5342 try writer.writeByte('(');
5343 try f.writeCValue(writer, container_ptr_val, .Other);5343 try f.writeCValue(writer, container_ptr_val, .Other);
5344 try writer.print(" + {}", .{try f.fmtIntLiteral(Type.usize, Value.one)});5344 try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, Value.one)});
5345 },5345 },
5346 }5346 }
53475347
...@@ -6448,10 +6448,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6448,10 +6448,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6448 //6448 //
6449 // Equivalent to:6449 // Equivalent to:
6450 // reduce: {6450 // reduce: {
6451 // var i: usize = 0;
6452 // var accum: T = init;6451 // var accum: T = init;
6453 // while (i < vec.len) : (i += 1) {6452 // for (vec) : (elem) {
6454 // accum = func(accum, vec[i]);6453 // accum = func(accum, elem);
6455 // }6454 // }
6456 // break :reduce accum;6455 // break :reduce accum;
6457 // }6456 // }
...@@ -7162,8 +7161,9 @@ fn stringLiteral(child_stream: anytype) StringLiteral(@TypeOf(child_stream)) {...@@ -7162,8 +7161,9 @@ fn stringLiteral(child_stream: anytype) StringLiteral(@TypeOf(child_stream)) {
7162 return .{ .counting_writer = std.io.countingWriter(child_stream) };7161 return .{ .counting_writer = std.io.countingWriter(child_stream) };
7163}7162}
71647163
7164const FormatStringContext = struct { str: []const u8, sentinel: ?u8 };
7165fn formatStringLiteral(7165fn formatStringLiteral(
7166 str: []const u8,7166 data: FormatStringContext,
7167 comptime fmt: []const u8,7167 comptime fmt: []const u8,
7168 _: std.fmt.FormatOptions,7168 _: std.fmt.FormatOptions,
7169 writer: anytype,7169 writer: anytype,
...@@ -7172,13 +7172,13 @@ fn formatStringLiteral(...@@ -7172,13 +7172,13 @@ fn formatStringLiteral(
71727172
7173 var literal = stringLiteral(writer);7173 var literal = stringLiteral(writer);
7174 try literal.start();7174 try literal.start();
7175 for (str) |c|7175 for (data.str) |c| try literal.writeChar(c);
7176 try literal.writeChar(c);7176 if (data.sentinel) |sentinel| if (sentinel != 0) try literal.writeChar(sentinel);
7177 try literal.end();7177 try literal.end();
7178}7178}
71797179
7180fn fmtStringLiteral(str: []const u8) std.fmt.Formatter(formatStringLiteral) {7180fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Formatter(formatStringLiteral) {
7181 return .{ .data = str };7181 return .{ .data = .{ .str = str, .sentinel = sentinel } };
7182}7182}
71837183
7184fn undefPattern(comptime IntType: type) IntType {7184fn undefPattern(comptime IntType: type) IntType {