mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
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
This commit is contained in:
parent
1fee9eac8b
commit
fad95741db
5 changed files with 35 additions and 4 deletions
|
|
@ -104,7 +104,6 @@ test "parse and render UNIX addresses" {
|
|||
}
|
||||
|
||||
test "resolve DNS" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
|
||||
if (builtin.os.tag == .windows) {
|
||||
|
|
|
|||
|
|
@ -6476,7 +6476,7 @@ pub fn dn_expand(
|
|||
p = msg.ptr + j;
|
||||
} else if (p[0] != 0) {
|
||||
if (dest != exp_dn.ptr) {
|
||||
dest.* = '.';
|
||||
dest[0] = '.';
|
||||
dest += 1;
|
||||
}
|
||||
var j = p[0];
|
||||
|
|
@ -6486,12 +6486,12 @@ pub fn dn_expand(
|
|||
}
|
||||
while (j != 0) {
|
||||
j -= 1;
|
||||
dest.* = p[0];
|
||||
dest[0] = p[0];
|
||||
dest += 1;
|
||||
p += 1;
|
||||
}
|
||||
} else {
|
||||
dest.* = 0;
|
||||
dest[0] = 0;
|
||||
if (len == std.math.maxInt(usize)) len = @ptrToInt(p) + 1 - @ptrToInt(comp_dn.ptr);
|
||||
return len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5795,6 +5795,10 @@ fn whileExpr(
|
|||
break :s &else_scope.base;
|
||||
}
|
||||
};
|
||||
// Remove the continue block and break block so that `continue` and `break`
|
||||
// control flow apply to outer loops; not this one.
|
||||
loop_scope.continue_block = 0;
|
||||
loop_scope.break_block = 0;
|
||||
const e = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node);
|
||||
if (!else_scope.endsWithNoReturn()) {
|
||||
loop_scope.break_count += 1;
|
||||
|
|
@ -5994,6 +5998,10 @@ fn forExpr(
|
|||
result: Zir.Inst.Ref,
|
||||
} = if (else_node != 0) blk: {
|
||||
const sub_scope = &else_scope.base;
|
||||
// Remove the continue block and break block so that `continue` and `break`
|
||||
// control flow apply to outer loops; not this one.
|
||||
loop_scope.continue_block = 0;
|
||||
loop_scope.break_block = 0;
|
||||
const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node);
|
||||
if (!else_scope.endsWithNoReturn()) {
|
||||
loop_scope.break_count += 1;
|
||||
|
|
|
|||
|
|
@ -210,3 +210,17 @@ test "for on slice with allowzero ptr" {
|
|||
try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
|
||||
comptime try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
|
||||
}
|
||||
|
||||
test "else continue outer for" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var i: usize = 6;
|
||||
var buf: [5]u8 = undefined;
|
||||
while (true) {
|
||||
i -= 1;
|
||||
for (buf[i..5]) |_| {
|
||||
return;
|
||||
} else continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -334,3 +334,13 @@ test "continue inline while loop" {
|
|||
}
|
||||
comptime assert(i == 5);
|
||||
}
|
||||
|
||||
test "else continue outer while" {
|
||||
var i: usize = 0;
|
||||
while (true) {
|
||||
i += 1;
|
||||
while (i > 5) {
|
||||
return;
|
||||
} else continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue