mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 21:38:33 +00:00
Treat blocks with "return" as "noreturn"
Block statements that end with "break" should not be considered "noreturn" for the enclosing scope, but other "noreturn" instructions (return, panic, compile error, etc.) should be. This differentiation necessitates handling "break" differently from the other "noreturn" instructions when inside a block statement.
This commit is contained in:
parent
33826a6a2e
commit
135b91aecd
@ -1967,6 +1967,9 @@ fn blockExpr(
|
||||
}
|
||||
|
||||
try blockExprStmts(gz, scope, statements);
|
||||
if (gz.endsWithNoReturn() and !gz.endsWithBreak()) {
|
||||
return Zir.Inst.Ref.unreachable_value;
|
||||
}
|
||||
return rvalue(gz, rl, .void_value, block_node);
|
||||
}
|
||||
|
||||
@ -9930,6 +9933,13 @@ const GenZir = struct {
|
||||
return tags[last_inst].isNoReturn();
|
||||
}
|
||||
|
||||
fn endsWithBreak(gz: GenZir) bool {
|
||||
if (gz.isEmpty()) return false;
|
||||
const tags = gz.astgen.instructions.items(.tag);
|
||||
const last_inst = gz.instructions.items[gz.instructions.items.len - 1];
|
||||
return tags[last_inst].isBreak();
|
||||
}
|
||||
|
||||
/// TODO all uses of this should be replaced with uses of `endsWithNoReturn`.
|
||||
fn refIsNoReturn(gz: GenZir, inst_ref: Zir.Inst.Ref) bool {
|
||||
if (inst_ref == .unreachable_value) return true;
|
||||
|
||||
13
src/Zir.zig
13
src/Zir.zig
@ -1250,6 +1250,19 @@ pub const Inst = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns whether the instruction is a "break". This differs from
|
||||
/// isNoReturn because a "break" in a block statement is not a
|
||||
/// "noreturn" for the outer scope, whereas the other "noreturn"
|
||||
/// instructions are.
|
||||
pub fn isBreak(tag: Tag) bool {
|
||||
return switch (tag) {
|
||||
.@"break",
|
||||
.break_inline,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// AstGen uses this to find out if `Ref.void_value` should be used in place
|
||||
/// of the result of a given instruction. This allows Sema to forego adding
|
||||
/// the instruction to the map after analysis.
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
export fn entry() void {
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// error
|
||||
// target=native
|
||||
//
|
||||
// :6:5: error: unreachable code
|
||||
// :2:5: note: control flow is diverted here
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user