aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-03-26 18:26:39 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-03-26 18:26:39 -0700
commita72bfd00cf07da50a94a024d6f74167aa41382c5 (patch)
tree8fe496f8fc343f58f8dc315dad4d5638ab303a8c
parenta217ad59c770eb3915f5b98f177a012181b7f48e (diff)
downloadzig-a72bfd00cf07da50a94a024d6f74167aa41382c5.tar.gz
zig-a72bfd00cf07da50a94a024d6f74167aa41382c5.zip
astgen: fix continue expressions
-rw-r--r--src/astgen.zig18
-rw-r--r--test/stage2/test.zig178
2 files changed, 97 insertions, 99 deletions
diff --git a/src/astgen.zig b/src/astgen.zig
index 664a37c9d1..d01bc46515 100644
--- a/src/astgen.zig
+++ b/src/astgen.zig
@@ -766,11 +766,9 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerErro
}
fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
- if (true) @panic("TODO update for zir-memory-layout");
- const tree = parent_scope.tree();
+ const parent_gz = parent_scope.getGenZir();
+ const tree = parent_gz.tree();
const node_datas = tree.nodes.items(.data);
- const main_tokens = tree.nodes.items(.main_token);
-
const break_label = node_datas[node].lhs;
// Look for the label in the scope.
@@ -779,10 +777,11 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE
switch (scope.tag) {
.gen_zir => {
const gen_zir = scope.cast(Scope.GenZir).?;
- const continue_block = gen_zir.continue_block orelse {
+ const continue_block = gen_zir.continue_block;
+ if (continue_block == 0) {
scope = gen_zir.parent;
continue;
- };
+ }
if (break_label != 0) blk: {
if (gen_zir.label) |*label| {
if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {
@@ -795,9 +794,8 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE
continue;
}
- _ = try addZirInstTag(mod, parent_scope, src, .break_void, .{
- .block = continue_block,
- });
+ // TODO emit a break_inline if the loop being continued is inline
+ _ = try parent_gz.addBreak(.@"break", continue_block, .void_value);
return zir.Inst.Ref.unreachable_value;
},
.local_val => scope = scope.cast(Scope.LocalVal).?.parent,
@@ -806,7 +804,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerE
const label_name = try mod.identifierTokenString(parent_scope, break_label);
return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name});
} else {
- return mod.failTok(parent_scope, src, "continue expression outside loop", .{});
+ return mod.failNode(parent_scope, node, "continue expression outside loop", .{});
},
}
}
diff --git a/test/stage2/test.zig b/test/stage2/test.zig
index 242a01b599..8131a37c04 100644
--- a/test/stage2/test.zig
+++ b/test/stage2/test.zig
@@ -1128,97 +1128,97 @@ pub fn addCases(ctx: *TestContext) !void {
, &[_][]const u8{":4:8: error: unable to infer variable type"});
}
- //{
- // var case = ctx.exe("break/continue", linux_x64);
+ {
+ var case = ctx.exe("break/continue", linux_x64);
- // // Break out of loop
- // case.addCompareOutput(
- // \\export fn _start() noreturn {
- // \\ while (true) {
- // \\ break;
- // \\ }
- // \\
- // \\ exit();
- // \\}
- // \\
- // \\fn exit() noreturn {
- // \\ asm volatile ("syscall"
- // \\ :
- // \\ : [number] "{rax}" (231),
- // \\ [arg1] "{rdi}" (0)
- // \\ : "rcx", "r11", "memory"
- // \\ );
- // \\ unreachable;
- // \\}
- // ,
- // "",
- // );
- // case.addCompareOutput(
- // \\export fn _start() noreturn {
- // \\ foo: while (true) {
- // \\ break :foo;
- // \\ }
- // \\
- // \\ exit();
- // \\}
- // \\
- // \\fn exit() noreturn {
- // \\ asm volatile ("syscall"
- // \\ :
- // \\ : [number] "{rax}" (231),
- // \\ [arg1] "{rdi}" (0)
- // \\ : "rcx", "r11", "memory"
- // \\ );
- // \\ unreachable;
- // \\}
- // ,
- // "",
- // );
+ // Break out of loop
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ while (true) {
+ \\ break;
+ \\ }
+ \\
+ \\ exit();
+ \\}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("syscall"
+ \\ :
+ \\ : [number] "{rax}" (231),
+ \\ [arg1] "{rdi}" (0)
+ \\ : "rcx", "r11", "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "",
+ );
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ foo: while (true) {
+ \\ break :foo;
+ \\ }
+ \\
+ \\ exit();
+ \\}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("syscall"
+ \\ :
+ \\ : [number] "{rax}" (231),
+ \\ [arg1] "{rdi}" (0)
+ \\ : "rcx", "r11", "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "",
+ );
- // // Continue in loop
- // case.addCompareOutput(
- // \\export fn _start() noreturn {
- // \\ var i: u64 = 0;
- // \\ while (true) : (i+=1) {
- // \\ if (i == 4) exit();
- // \\ continue;
- // \\ }
- // \\}
- // \\
- // \\fn exit() noreturn {
- // \\ asm volatile ("syscall"
- // \\ :
- // \\ : [number] "{rax}" (231),
- // \\ [arg1] "{rdi}" (0)
- // \\ : "rcx", "r11", "memory"
- // \\ );
- // \\ unreachable;
- // \\}
- // ,
- // "",
- // );
- // case.addCompareOutput(
- // \\export fn _start() noreturn {
- // \\ var i: u64 = 0;
- // \\ foo: while (true) : (i+=1) {
- // \\ if (i == 4) exit();
- // \\ continue :foo;
- // \\ }
- // \\}
- // \\
- // \\fn exit() noreturn {
- // \\ asm volatile ("syscall"
- // \\ :
- // \\ : [number] "{rax}" (231),
- // \\ [arg1] "{rdi}" (0)
- // \\ : "rcx", "r11", "memory"
- // \\ );
- // \\ unreachable;
- // \\}
- // ,
- // "",
- // );
- //}
+ // Continue in loop
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ var i: u64 = 0;
+ \\ while (true) : (i+=1) {
+ \\ if (i == 4) exit();
+ \\ continue;
+ \\ }
+ \\}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("syscall"
+ \\ :
+ \\ : [number] "{rax}" (231),
+ \\ [arg1] "{rdi}" (0)
+ \\ : "rcx", "r11", "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "",
+ );
+ case.addCompareOutput(
+ \\export fn _start() noreturn {
+ \\ var i: u64 = 0;
+ \\ foo: while (true) : (i+=1) {
+ \\ if (i == 4) exit();
+ \\ continue :foo;
+ \\ }
+ \\}
+ \\
+ \\fn exit() noreturn {
+ \\ asm volatile ("syscall"
+ \\ :
+ \\ : [number] "{rax}" (231),
+ \\ [arg1] "{rdi}" (0)
+ \\ : "rcx", "r11", "memory"
+ \\ );
+ \\ unreachable;
+ \\}
+ ,
+ "",
+ );
+ }
{
var case = ctx.exe("unused labels", linux_x64);