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(...@@ -2373,8 +2373,8 @@ fn labeledBlockExpr(
2373 try astgen.appendErrorTok(label_token, "unused block label", .{});2373 try astgen.appendErrorTok(label_token, "unused block label", .{});
2374 }2374 }
23752375
2376 const zir_datas = gz.astgen.instructions.items(.data);2376 const zir_datas = astgen.instructions.items(.data);
2377 const zir_tags = gz.astgen.instructions.items(.tag);2377 const zir_tags = astgen.instructions.items(.tag);
2378 const strat = ri.rl.strategy(&block_scope);2378 const strat = ri.rl.strategy(&block_scope);
2379 switch (strat.tag) {2379 switch (strat.tag) {
2380 .break_void => {2380 .break_void => {
...@@ -2396,6 +2396,10 @@ fn labeledBlockExpr(...@@ -2396,6 +2396,10 @@ fn labeledBlockExpr(
2396 // it as the break operand.2396 // it as the break operand.
2397 // This corresponds to similar code in `setCondBrPayloadElideBlockStorePtr`.2397 // This corresponds to similar code in `setCondBrPayloadElideBlockStorePtr`.
2398 if (block_scope.rl_ty_inst != .none) {2398 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 );
2399 for (block_scope.labeled_breaks.items) |br| {2403 for (block_scope.labeled_breaks.items) |br| {
2400 // We expect the `store_to_block_ptr` to be created between 1-3 instructions2404 // We expect the `store_to_block_ptr` to be created between 1-3 instructions
2401 // prior to the break.2405 // prior to the break.
...@@ -2404,12 +2408,28 @@ fn labeledBlockExpr(...@@ -2404,12 +2408,28 @@ fn labeledBlockExpr(
2404 if (zir_tags[search_index] == .store_to_block_ptr and2408 if (zir_tags[search_index] == .store_to_block_ptr and
2405 zir_datas[search_index].bin.lhs == block_scope.rl_ptr)2409 zir_datas[search_index].bin.lhs == block_scope.rl_ptr)
2406 {2410 {
2407 zir_tags[search_index] = .as;2411 const break_data = &zir_datas[br.br].@"break";
2408 zir_datas[search_index].bin = .{2412 const break_src: i32 = @bitCast(astgen.extra.items[
2409 .lhs = block_scope.rl_ty_inst,2413 break_data.payload_index +
2410 .rhs = zir_datas[br.br].@"break".operand,2414 std.meta.fieldIndex(Zir.Inst.Break, "operand_src_node").?
2411 };2415 ]);
2412 zir_datas[br.br].@"break".operand = indexToRef(search_index);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);
2413 break;2433 break;
2414 }2434 }
2415 } else unreachable;2435 } else unreachable;
...@@ -2530,19 +2550,21 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2530,19 +2550,21 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2530 // For some instructions, modify the zir data2550 // For some instructions, modify the zir data
2531 // so we can avoid a separate ensure_result_used instruction.2551 // so we can avoid a separate ensure_result_used instruction.
2532 .call, .field_call => {2552 .call, .field_call => {
2533 const extra_index = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;2553 const break_extra = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;
2534 const slot = &gz.astgen.extra.items[extra_index];2554 comptime assert(std.meta.fieldIndex(Zir.Inst.Call, "flags") ==
2535 var flags = @as(Zir.Inst.Call.Flags, @bitCast(slot.*));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 ]);
2536 flags.ensure_result_used = true;2559 flags.ensure_result_used = true;
2537 slot.* = @as(u32, @bitCast(flags));
2538 break :b true;2560 break :b true;
2539 },2561 },
2540 .builtin_call => {2562 .builtin_call => {
2541 const extra_index = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;2563 const break_extra = gz.astgen.instructions.items(.data)[inst].pl_node.payload_index;
2542 const slot = &gz.astgen.extra.items[extra_index];2564 const flags: *Zir.Inst.BuiltinCall.Flags = @ptrCast(&gz.astgen.extra.items[
2543 var flags = @as(Zir.Inst.BuiltinCall.Flags, @bitCast(slot.*));2565 break_extra + std.meta.fieldIndex(Zir.Inst.BuiltinCall, "flags").?
2566 ]);
2544 flags.ensure_result_used = true;2567 flags.ensure_result_used = true;
2545 slot.* = @as(u32, @bitCast(flags));
2546 break :b true;2568 break :b true;
2547 },2569 },
25482570
...@@ -6106,14 +6128,12 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6106,14 +6128,12 @@ fn setCondBrPayloadElideBlockStorePtr(
6106 const zir_tags = astgen.instructions.items(.tag);6128 const zir_tags = astgen.instructions.items(.tag);
6107 const zir_datas = astgen.instructions.items(.data);6129 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{
6110 .condition = cond,6132 .condition = cond,
6111 .then_body_len = then_body_len,6133 .then_body_len = then_body_len,
6112 .else_body_len = else_body_len,6134 .else_body_len = else_body_len,
6113 });6135 });
6114 zir_datas[condbr].pl_node.payload_index = condbr_pl;6136 zir_datas[condbr].pl_node.payload_index = condbr_extra;
6115 const then_body_len_index = condbr_pl + 1;
6116 const else_body_len_index = condbr_pl + 2;
61176137
6118 // The break instructions need to have their operands coerced if the6138 // The break instructions need to have their operands coerced if the
6119 // switch's result location is a `ty`. In this case we overwrite the6139 // switch's result location is a `ty`. In this case we overwrite the
...@@ -6128,7 +6148,9 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6128,7 +6148,9 @@ fn setCondBrPayloadElideBlockStorePtr(
6128 if (then_scope.rl_ty_inst != .none and has_then_break) {6148 if (then_scope.rl_ty_inst != .none and has_then_break) {
6129 then_as_inst = src_inst;6149 then_as_inst = src_inst;
6130 } else {6150 } 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;
6132 continue;6154 continue;
6133 }6155 }
6134 }6156 }
...@@ -6144,7 +6166,9 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6144,7 +6166,9 @@ fn setCondBrPayloadElideBlockStorePtr(
6144 if (else_scope.rl_ty_inst != .none and has_else_break) {6166 if (else_scope.rl_ty_inst != .none and has_else_break) {
6145 else_as_inst = src_inst;6167 else_as_inst = src_inst;
6146 } else {6168 } 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;
6148 continue;6172 continue;
6149 }6173 }
6150 }6174 }
...@@ -7247,11 +7271,11 @@ fn switchExpr(...@@ -7247,11 +7271,11 @@ fn switchExpr(
7247 assert(!strat.elide_store_to_block_ptr_instructions);7271 assert(!strat.elide_store_to_block_ptr_instructions);
7248 const last_inst = payloads.items[end_index - 1];7272 const last_inst = payloads.items[end_index - 1];
7249 if (zir_tags[last_inst] == .@"break") {7273 if (zir_tags[last_inst] == .@"break") {
7250 const inst_data = zir_datas[last_inst].@"break";7274 const break_data = &zir_datas[last_inst].@"break";
7251 const block_inst = astgen.extra.items[inst_data.payload_index];7275 const block_inst = astgen.extra.items[
7252 if (block_inst == switch_block) {7276 break_data.payload_index + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?
7253 zir_datas[last_inst].@"break".operand = .void_value;7277 ];
7254 }7278 if (block_inst == switch_block) break_data.operand = .void_value;
7255 }7279 }
7256 },7280 },
7257 }7281 }
...@@ -11648,40 +11672,47 @@ const GenZir = struct {...@@ -11648,40 +11672,47 @@ const GenZir = struct {
11648 if (align_body.len != 0) {11672 if (align_body.len != 0) {
11649 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));11673 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
11650 astgen.appendBodyWithFixups(align_body);11674 astgen.appendBodyWithFixups(align_body);
11651 const inst_data = zir_datas[align_body[align_body.len - 1]].@"break";11675 const break_extra = zir_datas[align_body[align_body.len - 1]].@"break".payload_index;
11652 astgen.extra.items[inst_data.payload_index] = new_index;11676 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11677 new_index;
11653 } else if (args.align_ref != .none) {11678 } else if (args.align_ref != .none) {
11654 astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref));11679 astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref));
11655 }11680 }
11656 if (addrspace_body.len != 0) {11681 if (addrspace_body.len != 0) {
11657 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));11682 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
11658 astgen.appendBodyWithFixups(addrspace_body);11683 astgen.appendBodyWithFixups(addrspace_body);
11659 const inst_data = zir_datas[addrspace_body[addrspace_body.len - 1]].@"break";11684 const break_extra =
11660 astgen.extra.items[inst_data.payload_index] = new_index;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;
11661 } else if (args.addrspace_ref != .none) {11688 } else if (args.addrspace_ref != .none) {
11662 astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref));11689 astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref));
11663 }11690 }
11664 if (section_body.len != 0) {11691 if (section_body.len != 0) {
11665 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));11692 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
11666 astgen.appendBodyWithFixups(section_body);11693 astgen.appendBodyWithFixups(section_body);
11667 const inst_data = zir_datas[section_body[section_body.len - 1]].@"break";11694 const break_extra =
11668 astgen.extra.items[inst_data.payload_index] = new_index;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;
11669 } else if (args.section_ref != .none) {11698 } else if (args.section_ref != .none) {
11670 astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref));11699 astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref));
11671 }11700 }
11672 if (cc_body.len != 0) {11701 if (cc_body.len != 0) {
11673 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));11702 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
11674 astgen.appendBodyWithFixups(cc_body);11703 astgen.appendBodyWithFixups(cc_body);
11675 const inst_data = zir_datas[cc_body[cc_body.len - 1]].@"break";11704 const break_extra = zir_datas[cc_body[cc_body.len - 1]].@"break".payload_index;
11676 astgen.extra.items[inst_data.payload_index] = new_index;11705 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11706 new_index;
11677 } else if (args.cc_ref != .none) {11707 } else if (args.cc_ref != .none) {
11678 astgen.extra.appendAssumeCapacity(@intFromEnum(args.cc_ref));11708 astgen.extra.appendAssumeCapacity(@intFromEnum(args.cc_ref));
11679 }11709 }
11680 if (ret_body.len != 0) {11710 if (ret_body.len != 0) {
11681 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));11711 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
11682 astgen.appendBodyWithFixups(ret_body);11712 astgen.appendBodyWithFixups(ret_body);
11683 const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";11713 const break_extra = zir_datas[ret_body[ret_body.len - 1]].@"break".payload_index;
11684 astgen.extra.items[inst_data.payload_index] = new_index;11714 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11715 new_index;
11685 } else if (ret_ref != .none) {11716 } else if (ret_ref != .none) {
11686 astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref));11717 astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref));
11687 }11718 }
...@@ -11736,8 +11767,9 @@ const GenZir = struct {...@@ -11736,8 +11767,9 @@ const GenZir = struct {
11736 if (ret_body.len != 0) {11767 if (ret_body.len != 0) {
11737 astgen.appendBodyWithFixups(ret_body);11768 astgen.appendBodyWithFixups(ret_body);
1173811769
11739 const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";11770 const break_extra = zir_datas[ret_body[ret_body.len - 1]].@"break".payload_index;
11740 astgen.extra.items[inst_data.payload_index] = new_index;11771 astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] =
11772 new_index;
11741 } else if (ret_ref != .none) {11773 } else if (ret_ref != .none) {
11742 astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref));11774 astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref));
11743 }11775 }
...@@ -12191,21 +12223,8 @@ const GenZir = struct {...@@ -12191,21 +12223,8 @@ const GenZir = struct {
12191 ) !Zir.Inst.Index {12223 ) !Zir.Inst.Index {
12192 const gpa = gz.astgen.gpa;12224 const gpa = gz.astgen.gpa;
12193 try gz.instructions.ensureUnusedCapacity(gpa, 1);12225 try gz.instructions.ensureUnusedCapacity(gpa, 1);
12194 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
1219512226
12196 const extra: Zir.Inst.Break = .{12227 const new_index = try gz.makeBreak(tag, block_inst, operand);
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 });
12209 gz.instructions.appendAssumeCapacity(new_index);12228 gz.instructions.appendAssumeCapacity(new_index);
12210 return new_index;12229 return new_index;
12211 }12230 }
...@@ -12216,23 +12235,7 @@ const GenZir = struct {...@@ -12216,23 +12235,7 @@ const GenZir = struct {
12216 block_inst: Zir.Inst.Index,12235 block_inst: Zir.Inst.Index,
12217 operand: Zir.Inst.Ref,12236 operand: Zir.Inst.Ref,
12218 ) !Zir.Inst.Index {12237 ) !Zir.Inst.Index {
12219 const gpa = gz.astgen.gpa;12238 return gz.makeBreakCommon(tag, block_inst, operand, null);
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;
12236 }12239 }
1223712240
12238 fn addBreakWithSrcNode(12241 fn addBreakWithSrcNode(
...@@ -12244,21 +12247,8 @@ const GenZir = struct {...@@ -12244,21 +12247,8 @@ const GenZir = struct {
12244 ) !Zir.Inst.Index {12247 ) !Zir.Inst.Index {
12245 const gpa = gz.astgen.gpa;12248 const gpa = gz.astgen.gpa;
12246 try gz.instructions.ensureUnusedCapacity(gpa, 1);12249 try gz.instructions.ensureUnusedCapacity(gpa, 1);
12247 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
1224812250
12249 const extra: Zir.Inst.Break = .{12251 const new_index = try gz.makeBreakWithSrcNode(tag, block_inst, operand, operand_src_node);
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 });
12262 gz.instructions.appendAssumeCapacity(new_index);12252 gz.instructions.appendAssumeCapacity(new_index);
12263 return new_index;12253 return new_index;
12264 }12254 }
...@@ -12269,21 +12259,33 @@ const GenZir = struct {...@@ -12269,21 +12259,33 @@ const GenZir = struct {
12269 block_inst: Zir.Inst.Index,12259 block_inst: Zir.Inst.Index,
12270 operand: Zir.Inst.Ref,12260 operand: Zir.Inst.Ref,
12271 operand_src_node: Ast.Node.Index,12261 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,
12272 ) !Zir.Inst.Index {12272 ) !Zir.Inst.Index {
12273 const gpa = gz.astgen.gpa;12273 const gpa = gz.astgen.gpa;
12274 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);12274 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 const new_index: Zir.Inst.Index = @intCast(gz.astgen.instructions.len);
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));
12282 gz.astgen.instructions.appendAssumeCapacity(.{12278 gz.astgen.instructions.appendAssumeCapacity(.{
12283 .tag = tag,12279 .tag = tag,
12284 .data = .{ .@"break" = .{12280 .data = .{ .@"break" = .{
12285 .operand = operand,12281 .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 }),
12287 } },12289 } },
12288 });12290 });
12289 return new_index;12291 return new_index;
src/Zir.zig+1-1
...@@ -2347,8 +2347,8 @@ pub const Inst = struct {...@@ -2347,8 +2347,8 @@ pub const Inst = struct {
2347 pub const Break = struct {2347 pub const Break = struct {
2348 pub const no_src_node = std.math.maxInt(i32);2348 pub const no_src_node = std.math.maxInt(i32);
23492349
2350 block_inst: Index,
2351 operand_src_node: i32,2350 operand_src_node: i32,
2351 block_inst: Index,
2352 };2352 };
23532353
2354 /// Trailing:2354 /// 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'