mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
stage2: add implicit return void where applicable
This commit is contained in:
parent
c306392b44
commit
25b1c00c72
@ -1210,6 +1210,12 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
|
||||
|
||||
try self.astGenBlock(&gen_scope.base, body_block);
|
||||
|
||||
const last_inst = gen_scope.instructions.items[gen_scope.instructions.items.len - 1];
|
||||
if (!last_inst.tag.isNoReturn()) {
|
||||
const src = tree.token_locs[body_block.rbrace].start;
|
||||
_ = try self.addZIRInst(&gen_scope.base, src, zir.Inst.ReturnVoid, .{}, .{});
|
||||
}
|
||||
|
||||
const fn_zir = try gen_scope_arena.allocator.create(Fn.ZIR);
|
||||
fn_zir.* = .{
|
||||
.body = .{
|
||||
@ -2686,7 +2692,7 @@ fn analyzeInstBlock(self: *Module, scope: *Scope, inst: *zir.Inst.Block) InnerEr
|
||||
|
||||
// Blocks must terminate with noreturn instruction.
|
||||
assert(child_block.instructions.items.len != 0);
|
||||
assert(child_block.instructions.items[child_block.instructions.items.len - 1].tag.isNoReturn());
|
||||
assert(child_block.instructions.items[child_block.instructions.items.len - 1].ty.isNoReturn());
|
||||
|
||||
// Need to set the type and emit the Block instruction. This allows machine code generation
|
||||
// to emit a jump instruction to after the block when it encounters the break.
|
||||
@ -3271,7 +3277,7 @@ fn analyzeInstCondBr(self: *Module, scope: *Scope, inst: *zir.Inst.CondBr) Inner
|
||||
defer false_block.instructions.deinit(self.gpa);
|
||||
try self.analyzeBody(&false_block.base, inst.positionals.false_body);
|
||||
|
||||
return self.addNewInstArgs(parent_block, inst.base.src, Type.initTag(.void), Inst.CondBr, Inst.Args(Inst.CondBr){
|
||||
return self.addNewInstArgs(parent_block, inst.base.src, Type.initTag(.noreturn), Inst.CondBr, Inst.Args(Inst.CondBr){
|
||||
.condition = cond,
|
||||
.true_body = .{ .instructions = try scope.arena().dupe(*Inst, true_block.instructions.items) },
|
||||
.false_body = .{ .instructions = try scope.arena().dupe(*Inst, false_block.instructions.items) },
|
||||
|
||||
@ -60,36 +60,6 @@ pub const Inst = struct {
|
||||
retvoid,
|
||||
sub,
|
||||
unreach,
|
||||
|
||||
/// Returns whether the instruction is one of the control flow "noreturn" types.
|
||||
/// Function calls do not count. When ZIR is generated, the compiler automatically
|
||||
/// emits an `Unreach` after a function call with the `noreturn` return type.
|
||||
pub fn isNoReturn(tag: Tag) bool {
|
||||
return switch (tag) {
|
||||
.add,
|
||||
.arg,
|
||||
.assembly,
|
||||
.bitcast,
|
||||
.block,
|
||||
.breakpoint,
|
||||
.call,
|
||||
.cmp,
|
||||
.constant,
|
||||
.isnonnull,
|
||||
.isnull,
|
||||
.ptrtoint,
|
||||
.sub,
|
||||
=> false,
|
||||
|
||||
.br,
|
||||
.brvoid,
|
||||
.condbr,
|
||||
.ret,
|
||||
.retvoid,
|
||||
.unreach,
|
||||
=> true,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn cast(base: *Inst, comptime T: type) ?*T {
|
||||
|
||||
@ -468,6 +468,10 @@ pub const Type = extern union {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isNoReturn(self: Type) bool {
|
||||
return self.zigTypeTag() == .NoReturn;
|
||||
}
|
||||
|
||||
/// Asserts that hasCodeGenBits() is true.
|
||||
pub fn abiAlignment(self: Type, target: Target) u32 {
|
||||
return switch (self.tag()) {
|
||||
|
||||
@ -81,6 +81,52 @@ pub const Inst = struct {
|
||||
condbr,
|
||||
isnull,
|
||||
isnonnull,
|
||||
|
||||
/// Returns whether the instruction is one of the control flow "noreturn" types.
|
||||
/// Function calls do not count.
|
||||
pub fn isNoReturn(tag: Tag) bool {
|
||||
return switch (tag) {
|
||||
.arg,
|
||||
.block,
|
||||
.breakpoint,
|
||||
.call,
|
||||
.@"const",
|
||||
.declref,
|
||||
.declref_str,
|
||||
.declval,
|
||||
.declval_in_module,
|
||||
.str,
|
||||
.int,
|
||||
.inttype,
|
||||
.ptrtoint,
|
||||
.fieldptr,
|
||||
.deref,
|
||||
.as,
|
||||
.@"asm",
|
||||
.@"fn",
|
||||
.fntype,
|
||||
.@"export",
|
||||
.primitive,
|
||||
.intcast,
|
||||
.bitcast,
|
||||
.elemptr,
|
||||
.add,
|
||||
.sub,
|
||||
.cmp,
|
||||
.isnull,
|
||||
.isnonnull,
|
||||
=> false,
|
||||
|
||||
.condbr,
|
||||
.@"unreachable",
|
||||
.@"return",
|
||||
.returnvoid,
|
||||
.@"break",
|
||||
.breakvoid,
|
||||
.compileerror,
|
||||
=> true,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn TagToType(tag: Tag) type {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user