authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-11 23:54:54-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-12 01:57:15-04:00
logce7acf1296f7d38e6ee1b24e7aa85864198dd8fa
tree1790707754b81bdef7bdd432e6a8c8dfafe049b9
parent2b5bd56a67a26cd4adff76b6e3bf542e97f91cc4

AstGen: fix src loc for invalid coercion in breaks


3 files changed, 106 insertions(+), 92 deletions(-)

src/AstGen.zig+93-91
......@@ -2373,8 +2373,8 @@ fn labeledBlockExpr(
23732373 try astgen.appendErrorTok(label_token, "unused block label", .{});
23742374 }
23752375
2376 const zir_datas = gz.astgen.instructions.items(.data);
2377 const zir_tags = gz.astgen.instructions.items(.tag);
2376 const zir_datas = astgen.instructions.items(.data);
2377 const zir_tags = astgen.instructions.items(.tag);
23782378 const strat = ri.rl.strategy(&block_scope);
23792379 switch (strat.tag) {
23802380 .break_void => {
......@@ -2396,6 +2396,10 @@ fn labeledBlockExpr(
23962396 // it as the break operand.
23972397 // This corresponds to similar code in `setCondBrPayloadElideBlockStorePtr`.
23982398 if (block_scope.rl_ty_inst != .none) {
2399 try astgen.extra.ensureUnusedCapacity(
2400 astgen.gpa,
2401 @typeInfo(Zir.Inst.As).Struct.fields.len * block_scope.labeled_breaks.items.len,
2402 );
23992403 for (block_scope.labeled_breaks.items) |br| {
24002404 // We expect the `store_to_block_ptr` to be created between 1-3 instructions
24012405 // prior to the break.
......@@ -2404,12 +2408,28 @@ fn labeledBlockExpr(
24042408 if (zir_tags[search_index] == .store_to_block_ptr and
24052409 zir_datas[search_index].bin.lhs == block_scope.rl_ptr)
24062410 {
2407 zir_tags[search_index] = .as;
2408 zir_datas[search_index].bin = .{
2409 .lhs = block_scope.rl_ty_inst,
2410 .rhs = zir_datas[br.br].@"break".operand,
2411 };
2412 zir_datas[br.br].@"break".operand = indexToRef(search_index);
2411 const break_data = &zir_datas[br.br].@"break";
2412 const break_src: i32 = @bitCast(astgen.extra.items[
2413 break_data.payload_index +
2414 std.meta.fieldIndex(Zir.Inst.Break, "operand_src_node").?
2415 ]);
2416 if (break_src == Zir.Inst.Break.no_src_node) {
2417 zir_tags[search_index] = .as;
2418 zir_datas[search_index].bin = .{
2419 .lhs = block_scope.rl_ty_inst,
2420 .rhs = break_data.operand,
2421 };
2422 } else {
2423 zir_tags[search_index] = .as_node;
2424 zir_datas[search_index] = .{ .pl_node = .{
2425 .src_node = break_src,
2426 .payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.As{
2427 .dest_type = block_scope.rl_ty_inst,
2428 .operand = break_data.operand,
2429 }),
2430 } };
2431 }
2432 break_data.operand = indexToRef(search_index);
24132433 break;
24142434 }
24152435 } else unreachable;
......@@ -2530,19 +2550,21 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
25302550 // For some instructions, modify the zir data
25312551 // so we can avoid a separate ensure_result_used instruction.
25322552 .call, .field_call => {
2533 const extra_index = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;
2534 const slot = &gz.astgen.extra.items[extra_index];
2535 var flags = @as(Zir.Inst.Call.Flags, @bitCast(slot.*));
2553 const break_extra = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;
2554 comptime assert(std.meta.fieldIndex(Zir.Inst.Call, "flags") ==
2555 std.meta.fieldIndex(Zir.Inst.FieldCall, "flags"));
2556 const flags: *Zir.Inst.Call.Flags = @ptrCast(&gz.astgen.extra.items[
2557 break_extra + std.meta.fieldIndex(Zir.Inst.Call, "flags").?
2558 ]);
25362559 flags.ensure_result_used = true;
2537 slot.* = @as(u32, @bitCast(flags));
25382560 break :b true;
25392561 },
25402562 .builtin_call => {
2541 const extra_index = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;
2542 const slot = &gz.astgen.extra.items[extra_index];
2543 var flags = @as(Zir.Inst.BuiltinCall.Flags, @bitCast(slot.*));
2563 const break_extra = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;
2564 const flags: *Zir.Inst.BuiltinCall.Flags = @ptrCast(&gz.astgen.extra.items[
2565 break_extra + std.meta.fieldIndex(Zir.Inst.BuiltinCall, "flags").?
2566 ]);
25442567 flags.ensure_result_used = true;
2545 slot.* = @as(u32, @bitCast(flags));
25462568 break :b true;
25472569 },
25482570
......@@ -6106,14 +6128,12 @@ fn setCondBrPayloadElideBlockStorePtr(
61066128 const zir_tags = astgen.instructions.items(.tag);
61076129 const zir_datas = astgen.instructions.items(.data);
61086130
6109 const condbr_pl = astgen.addExtraAssumeCapacity(Zir.Inst.CondBr{
6131 const condbr_extra = astgen.addExtraAssumeCapacity(Zir.Inst.CondBr{
61106132 .condition = cond,
61116133 .then_body_len = then_body_len,
61126134 .else_body_len = else_body_len,
61136135 });
6114 zir_datas[condbr].pl_node.payload_index = condbr_pl;
6115 const then_body_len_index = condbr_pl + 1;
6116 const else_body_len_index = condbr_pl + 2;
6136 zir_datas[condbr].pl_node.payload_index = condbr_extra;
61176137
61186138 // The break instructions need to have their operands coerced if the
61196139 // switch's result location is a `ty`. In this case we overwrite the
......@@ -6128,7 +6148,9 @@ fn setCondBrPayloadElideBlockStorePtr(
61286148 if (then_scope.rl_ty_inst != .none and has_then_break) {
61296149 then_as_inst = src_inst;
61306150 } else {
6131 astgen.extra.items[then_body_len_index] -= 1;
6151 astgen.extra.items[
6152 condbr_extra + std.meta.fieldIndex(Zir.Inst.CondBr, "then_body_len").?
6153 ] -= 1;
61326154 continue;
61336155 }
61346156 }
......@@ -6144,7 +6166,9 @@ fn setCondBrPayloadElideBlockStorePtr(
61446166 if (else_scope.rl_ty_inst != .none and has_else_break) {
61456167 else_as_inst = src_inst;
61466168 } else {
6147 astgen.extra.items[else_body_len_index] -= 1;
6169 astgen.extra.items[
6170 condbr_extra + std.meta.fieldIndex(Zir.Inst.CondBr, "else_body_len").?
6171 ] -= 1;
61486172 continue;
61496173 }
61506174 }
......@@ -7247,11 +7271,11 @@ fn switchExpr(
72477271 assert(!strat.elide_store_to_block_ptr_instructions);
72487272 const last_inst = payloads.items[end_index - 1];
72497273 if (zir_tags[last_inst] == .@"break") {
7250 const inst_data = zir_datas[last_inst].@"break";
7251 const block_inst = astgen.extra.items[inst_data.payload_index];
7252 if (block_inst == switch_block) {
7253 zir_datas[last_inst].@"break".operand = .void_value;
7254 }
7274 const break_data = &zir_datas[last_inst].@"break";
7275 const block_inst = astgen.extra.items[
7276 break_data.payload_index + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?
7277 ];
7278 if (block_inst == switch_block) break_data.operand = .void_value;
72557279 }
72567280 },
72577281 }
......@@ -11648,40 +11672,47 @@ const GenZir = struct {
1164811672 if (align_body.len != 0) {
1164911673 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
1165011674 astgen.appendBodyWithFixups(align_body);
11651 const inst_data = zir_datas[align_body[align_body.len - 1]].@"break";
11652 astgen.extra.items[inst_data.payload_index] = new_index;
11675 const break_extra = zir_datas[align_body[align_body.len - 1]].@"break".payload_index;
11676 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11677 new_index;
1165311678 } else if (args.align_ref != .none) {
1165411679 astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref));
1165511680 }
1165611681 if (addrspace_body.len != 0) {
1165711682 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
1165811683 astgen.appendBodyWithFixups(addrspace_body);
11659 const inst_data = zir_datas[addrspace_body[addrspace_body.len - 1]].@"break";
11660 astgen.extra.items[inst_data.payload_index] = new_index;
11684 const break_extra =
11685 zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".payload_index;
11686 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11687 new_index;
1166111688 } else if (args.addrspace_ref != .none) {
1166211689 astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref));
1166311690 }
1166411691 if (section_body.len != 0) {
1166511692 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
1166611693 astgen.appendBodyWithFixups(section_body);
11667 const inst_data = zir_datas[section_body[section_body.len - 1]].@"break";
11668 astgen.extra.items[inst_data.payload_index] = new_index;
11694 const break_extra =
11695 zir_datas[section_body[section_body.len - 1]].@"break".payload_index;
11696 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11697 new_index;
1166911698 } else if (args.section_ref != .none) {
1167011699 astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref));
1167111700 }
1167211701 if (cc_body.len != 0) {
1167311702 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
1167411703 astgen.appendBodyWithFixups(cc_body);
11675 const inst_data = zir_datas[cc_body[cc_body.len - 1]].@"break";
11676 astgen.extra.items[inst_data.payload_index] = new_index;
11704 const break_extra = zir_datas[cc_body[cc_body.len - 1]].@"break".payload_index;
11705 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11706 new_index;
1167711707 } else if (args.cc_ref != .none) {
1167811708 astgen.extra.appendAssumeCapacity(@intFromEnum(args.cc_ref));
1167911709 }
1168011710 if (ret_body.len != 0) {
1168111711 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
1168211712 astgen.appendBodyWithFixups(ret_body);
11683 const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";
11684 astgen.extra.items[inst_data.payload_index] = new_index;
11713 const break_extra = zir_datas[ret_body[ret_body.len - 1]].@"break".payload_index;
11714 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11715 new_index;
1168511716 } else if (ret_ref != .none) {
1168611717 astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref));
1168711718 }
......@@ -11736,8 +11767,9 @@ const GenZir = struct {
1173611767 if (ret_body.len != 0) {
1173711768 astgen.appendBodyWithFixups(ret_body);
1173811769
11739 const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";
11740 astgen.extra.items[inst_data.payload_index] = new_index;
11770 const break_extra = zir_datas[ret_body[ret_body.len - 1]].@"break".payload_index;
11771 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11772 new_index;
1174111773 } else if (ret_ref != .none) {
1174211774 astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref));
1174311775 }
......@@ -12191,21 +12223,8 @@ const GenZir = struct {
1219112223 ) !Zir.Inst.Index {
1219212224 const gpa = gz.astgen.gpa;
1219312225 try gz.instructions.ensureUnusedCapacity(gpa, 1);
12194 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
1219512226
12196 const extra: Zir.Inst.Break = .{
12197 .block_inst = block_inst,
12198 .operand_src_node = Zir.Inst.Break.no_src_node,
12199 };
12200 const payload_index = try gz.astgen.addExtra(extra);
12201 const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len));
12202 gz.astgen.instructions.appendAssumeCapacity(.{
12203 .tag = tag,
12204 .data = .{ .@"break" = .{
12205 .operand = operand,
12206 .payload_index = payload_index,
12207 } },
12208 });
12227 const new_index = try gz.makeBreak(tag, block_inst, operand);
1220912228 gz.instructions.appendAssumeCapacity(new_index);
1221012229 return new_index;
1221112230 }
......@@ -12216,23 +12235,7 @@ const GenZir = struct {
1221612235 block_inst: Zir.Inst.Index,
1221712236 operand: Zir.Inst.Ref,
1221812237 ) !Zir.Inst.Index {
12219 const gpa = gz.astgen.gpa;
12220 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
12221
12222 const extra: Zir.Inst.Break = .{
12223 .block_inst = block_inst,
12224 .operand_src_node = Zir.Inst.Break.no_src_node,
12225 };
12226 const payload_index = try gz.astgen.addExtra(extra);
12227 const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len));
12228 gz.astgen.instructions.appendAssumeCapacity(.{
12229 .tag = tag,
12230 .data = .{ .@"break" = .{
12231 .operand = operand,
12232 .payload_index = payload_index,
12233 } },
12234 });
12235 return new_index;
12238 return gz.makeBreakCommon(tag, block_inst, operand, null);
1223612239 }
1223712240
1223812241 fn addBreakWithSrcNode(
......@@ -12244,21 +12247,8 @@ const GenZir = struct {
1224412247 ) !Zir.Inst.Index {
1224512248 const gpa = gz.astgen.gpa;
1224612249 try gz.instructions.ensureUnusedCapacity(gpa, 1);
12247 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
1224812250
12249 const extra: Zir.Inst.Break = .{
12250 .block_inst = block_inst,
12251 .operand_src_node = gz.nodeIndexToRelative(operand_src_node),
12252 };
12253 const payload_index = try gz.astgen.addExtra(extra);
12254 const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len));
12255 gz.astgen.instructions.appendAssumeCapacity(.{
12256 .tag = tag,
12257 .data = .{ .@"break" = .{
12258 .operand = operand,
12259 .payload_index = payload_index,
12260 } },
12261 });
12251 const new_index = try gz.makeBreakWithSrcNode(tag, block_inst, operand, operand_src_node);
1226212252 gz.instructions.appendAssumeCapacity(new_index);
1226312253 return new_index;
1226412254 }
......@@ -12269,21 +12259,33 @@ const GenZir = struct {
1226912259 block_inst: Zir.Inst.Index,
1227012260 operand: Zir.Inst.Ref,
1227112261 operand_src_node: Ast.Node.Index,
12262 ) !Zir.Inst.Index {
12263 return gz.makeBreakCommon(tag, block_inst, operand, operand_src_node);
12264 }
12265
12266 fn makeBreakCommon(
12267 gz: *GenZir,
12268 tag: Zir.Inst.Tag,
12269 block_inst: Zir.Inst.Index,
12270 operand: Zir.Inst.Ref,
12271 operand_src_node: ?Ast.Node.Index,
1227212272 ) !Zir.Inst.Index {
1227312273 const gpa = gz.astgen.gpa;
1227412274 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
12275 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Break).Struct.fields.len);
1227512276
12276 const extra: Zir.Inst.Break = .{
12277 .block_inst = block_inst,
12278 .operand_src_node = gz.nodeIndexToRelative(operand_src_node),
12279 };
12280 const payload_index = try gz.astgen.addExtra(extra);
12281 const new_index = @as(Zir.Inst.Index, @intCast(gz.astgen.instructions.len));
12277 const new_index: Zir.Inst.Index = @intCast(gz.astgen.instructions.len);
1228212278 gz.astgen.instructions.appendAssumeCapacity(.{
1228312279 .tag = tag,
1228412280 .data = .{ .@"break" = .{
1228512281 .operand = operand,
12286 .payload_index = payload_index,
12282 .payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Break{
12283 .operand_src_node = if (operand_src_node) |src_node|
12284 gz.nodeIndexToRelative(src_node)
12285 else
12286 Zir.Inst.Break.no_src_node,
12287 .block_inst = block_inst,
12288 }),
1228712289 } },
1228812290 });
1228912291 return new_index;
src/Zir.zig+1-1
......@@ -2347,8 +2347,8 @@ pub const Inst = struct {
23472347 pub const Break = struct {
23482348 pub const no_src_node = std.math.maxInt(i32);
23492349
2350 block_inst: Index,
23512350 operand_src_node: i32,
2351 block_inst: Index,
23522352 };
23532353
23542354 /// Trailing:
test/cases/compile_errors/invalid_coercion_in_labeled_break.zig created+12
......@@ -0,0 +1,12 @@
1export fn invalidBreak() u8 {
2 const result: u8 = label: {
3 break :label 256;
4 };
5 return result;
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:22: error: type 'u8' cannot represent integer value '256'