authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-15 02:48:35-04:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-04-17 02:30:10+03:00
log7e0c6d7edc538b1648792e73b0c8aab1a35d0bff
treec6d77d4627ec5485df971a97bf0af4faedcf28e6
parent7fad555e5e16e6cb71554981394387a0622093b0

Sema: fix empty infinite loops

Closes #15284

4 files changed, 29 insertions(+), 4 deletions(-)

src/Sema.zig+4-4
......@@ -5225,17 +5225,17 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
52255225
52265226 try sema.analyzeBody(&loop_block, body);
52275227
5228 if (sema.typeOf(Air.indexToRef(loop_block.instructions.items[loop_block.instructions.items.len - 1])).isNoReturn()) {
5228 const loop_block_len = loop_block.instructions.items.len;
5229 if (loop_block_len > 0 and sema.typeOf(Air.indexToRef(loop_block.instructions.items[loop_block_len - 1])).isNoReturn()) {
52295230 // If the loop ended with a noreturn terminator, then there is no way for it to loop,
52305231 // so we can just use the block instead.
52315232 try child_block.instructions.appendSlice(gpa, loop_block.instructions.items);
52325233 } else {
52335234 try child_block.instructions.append(gpa, loop_inst);
52345235
5235 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
5236 loop_block.instructions.items.len);
5236 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + loop_block_len);
52375237 sema.air_instructions.items(.data)[loop_inst].ty_pl.payload = sema.addExtraAssumeCapacity(
5238 Air.Block{ .body_len = @intCast(u32, loop_block.instructions.items.len) },
5238 Air.Block{ .body_len = @intCast(u32, loop_block_len) },
52395239 );
52405240 sema.air_extra.appendSliceAssumeCapacity(loop_block.instructions.items);
52415241 }
test/standalone.zig+4
......@@ -218,6 +218,10 @@ pub const build_cases = [_]BuildCase{
218218 // .build_root = "test/standalone/options",
219219 // .import = @import("standalone/options/build.zig"),
220220 //},
221 .{
222 .build_root = "test/standalone/strip_empty_loop",
223 .import = @import("standalone/strip_empty_loop/build.zig"),
224 },
221225};
222226
223227const std = @import("std");
test/standalone/strip_empty_loop/build.zig created+18
......@@ -0,0 +1,18 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test the program");
5 b.default_step = test_step;
6
7 const optimize = std.builtin.OptimizeMode.Debug;
8 const target = std.zig.CrossTarget{};
9
10 const main = b.addExecutable(.{
11 .name = "main",
12 .root_source_file = .{ .path = "main.zig" },
13 .optimize = optimize,
14 .target = target,
15 });
16 main.strip = true;
17 test_step.dependOn(&main.step);
18}
test/standalone/strip_empty_loop/main.zig created+3
......@@ -0,0 +1,3 @@
1pub fn main() noreturn {
2 while (true) {} // When built without debug info, this produces an Air loop with no instructions
3}