Skip to content

Commit fad9574

Browse files
committed
AstGen: fix loop control flow applying to wrong loop
In the case of 'continue' or 'break' inside the 'else' block of a 'while' or 'for' loop. Closes #12109
1 parent 1fee9ea commit fad9574

File tree

5 files changed

+35
-4
lines changed

5 files changed

+35
-4
lines changed

lib/std/net/test.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ test "parse and render UNIX addresses" {
104104
}
105105

106106
test "resolve DNS" {
107-
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
108107
if (builtin.os.tag == .wasi) return error.SkipZigTest;
109108

110109
if (builtin.os.tag == .windows) {

lib/std/os.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6476,7 +6476,7 @@ pub fn dn_expand(
64766476
p = msg.ptr + j;
64776477
} else if (p[0] != 0) {
64786478
if (dest != exp_dn.ptr) {
6479-
dest.* = '.';
6479+
dest[0] = '.';
64806480
dest += 1;
64816481
}
64826482
var j = p[0];
@@ -6486,12 +6486,12 @@ pub fn dn_expand(
64866486
}
64876487
while (j != 0) {
64886488
j -= 1;
6489-
dest.* = p[0];
6489+
dest[0] = p[0];
64906490
dest += 1;
64916491
p += 1;
64926492
}
64936493
} else {
6494-
dest.* = 0;
6494+
dest[0] = 0;
64956495
if (len == std.math.maxInt(usize)) len = @ptrToInt(p) + 1 - @ptrToInt(comp_dn.ptr);
64966496
return len;
64976497
}

src/AstGen.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5795,6 +5795,10 @@ fn whileExpr(
57955795
break :s &else_scope.base;
57965796
}
57975797
};
5798+
// Remove the continue block and break block so that `continue` and `break`
5799+
// control flow apply to outer loops; not this one.
5800+
loop_scope.continue_block = 0;
5801+
loop_scope.break_block = 0;
57985802
const e = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node);
57995803
if (!else_scope.endsWithNoReturn()) {
58005804
loop_scope.break_count += 1;
@@ -5994,6 +5998,10 @@ fn forExpr(
59945998
result: Zir.Inst.Ref,
59955999
} = if (else_node != 0) blk: {
59966000
const sub_scope = &else_scope.base;
6001+
// Remove the continue block and break block so that `continue` and `break`
6002+
// control flow apply to outer loops; not this one.
6003+
loop_scope.continue_block = 0;
6004+
loop_scope.break_block = 0;
59976005
const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node);
59986006
if (!else_scope.endsWithNoReturn()) {
59996007
loop_scope.break_count += 1;

test/behavior/for.zig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,17 @@ test "for on slice with allowzero ptr" {
210210
try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
211211
comptime try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
212212
}
213+
214+
test "else continue outer for" {
215+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
216+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
217+
218+
var i: usize = 6;
219+
var buf: [5]u8 = undefined;
220+
while (true) {
221+
i -= 1;
222+
for (buf[i..5]) |_| {
223+
return;
224+
} else continue;
225+
}
226+
}

test/behavior/while.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,13 @@ test "continue inline while loop" {
334334
}
335335
comptime assert(i == 5);
336336
}
337+
338+
test "else continue outer while" {
339+
var i: usize = 0;
340+
while (true) {
341+
i += 1;
342+
while (i > 5) {
343+
return;
344+
} else continue;
345+
}
346+
}

0 commit comments

Comments
 (0)