aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2020-12-26 02:36:12 +0200
committerVeikka Tuominen <git@vexu.eu>2020-12-26 02:36:12 +0200
commita50759325c95ad7dfd1fbf029759cf0a2608b3ab (patch)
tree8bdf7813a7b82e743ffc3dbc589314c94ba9473d /src
parent40aad4f47e1ab02a1ff6109f4b6f06af00d1f503 (diff)
downloadzig-a50759325c95ad7dfd1fbf029759cf0a2608b3ab.tar.gz
zig-a50759325c95ad7dfd1fbf029759cf0a2608b3ab.zip
stage2: add error for unused labels
Diffstat (limited to 'src')
-rw-r--r--src/Module.zig2
-rw-r--r--src/astgen.zig23
2 files changed, 20 insertions, 5 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 3806c0dea8..c0b7011f43 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -804,7 +804,7 @@ pub const Scope = struct {
pub const Label = struct {
token: ast.TokenIndex,
block_inst: *zir.Inst.Block,
- result_loc: astgen.ResultLoc,
+ used: bool = false,
};
};
diff --git a/src/astgen.zig b/src/astgen.zig
index c4ac5b5fc9..7b6349d4a8 100644
--- a/src/astgen.zig
+++ b/src/astgen.zig
@@ -348,8 +348,9 @@ fn breakExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpr
const block_inst = blk: {
if (node.getLabel()) |break_label| {
- if (gen_zir.label) |label| {
+ if (gen_zir.label) |*label| {
if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {
+ label.used = true;
break :blk label.block_inst;
}
}
@@ -407,8 +408,9 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
continue;
};
if (node.getLabel()) |break_label| blk: {
- if (gen_zir.label) |label| {
+ if (gen_zir.label) |*label| {
if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) {
+ label.used = true;
break :blk;
}
}
@@ -485,6 +487,9 @@ fn labeledBlockExpr(
defer block_scope.instructions.deinit(mod.gpa);
try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements());
+ if (!block_scope.label.?.used) {
+ return mod.fail(parent_scope, tree.token_locs[block_node.label].start, "unused block label", .{});
+ }
block_inst.positionals.body.instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items);
try gen_zir.instructions.append(mod.gpa, &block_inst.base);
@@ -1398,7 +1403,7 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
loop_scope.break_block = while_block;
loop_scope.continue_block = cond_block;
if (while_node.label) |some| {
- loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{
+ loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{
.token = some,
.block_inst = while_block,
});
@@ -1465,6 +1470,11 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W
condbr.positionals.else_body = .{
.instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items),
};
+ if (loop_scope.label) |some| {
+ if (!some.used) {
+ return mod.fail(scope, tree.token_locs[some.token].start, "unused while label", .{});
+ }
+ }
return &while_block.base;
}
@@ -1555,7 +1565,7 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For)
loop_scope.break_block = for_block;
loop_scope.continue_block = cond_block;
if (for_node.label) |some| {
- loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{
+ loop_scope.label = @as(?Scope.GenZIR.Label, Scope.GenZIR.Label{
.token = some,
.block_inst = for_block,
});
@@ -1646,6 +1656,11 @@ fn forExpr(mod: *Module, scope: *Scope, rl: ResultLoc, for_node: *ast.Node.For)
condbr.positionals.else_body = .{
.instructions = try else_scope.arena.dupe(*zir.Inst, else_scope.instructions.items),
};
+ if (loop_scope.label) |some| {
+ if (!some.used) {
+ return mod.fail(scope, tree.token_locs[some.token].start, "unused for label", .{});
+ }
+ }
return &for_block.base;
}