Skip to content

Commit

Permalink
Sema: add error for recursive inline call
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexu committed Dec 19, 2022
1 parent 6511afc commit c959dba
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ pub const Block = struct {
/// It is shared among all the blocks in an inline or comptime called
/// function.
pub const Inlining = struct {
func: ?*Module.Fn,
comptime_result: Air.Inst.Ref,
merges: Merges,
};
Expand Down Expand Up @@ -6435,6 +6436,16 @@ fn analyzeCall(
});
}

const recursive_msg = "inline call is recursive";
var head = if (!is_comptime_call) block else null;
while (head) |some| {
const inlining = some.inlining orelse break;
if (inlining.func == module_fn) {
return sema.fail(block, call_src, recursive_msg, .{});
}
head = some.parent;
}

// Analyze the ZIR. The same ZIR gets analyzed into a runtime function
// or an inlined call depending on what union tag the `label` field is
// set to in the `Block`.
Expand All @@ -6448,6 +6459,7 @@ fn analyzeCall(
// This one is shared among sub-blocks within the same callee, but not
// shared among the entire inline/comptime call stack.
var inlining: Block.Inlining = .{
.func = if (!is_comptime_call) module_fn else null,
.comptime_result = undefined,
.merges = .{
.results = .{},
Expand Down Expand Up @@ -6657,6 +6669,7 @@ fn analyzeCall(
error.ComptimeReturn => break :result inlining.comptime_result,
error.AnalysisFail => {
const err_msg = sema.err orelse return err;
if (std.mem.eql(u8, err_msg.msg, recursive_msg)) return err;
try sema.errNote(block, call_src, err_msg, "called from here", .{});
err_msg.clearTrace(sema.gpa);
return err;
Expand Down
12 changes: 12 additions & 0 deletions test/cases/compile_errors/recursive_inline_fn.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
inline fn foo() void {
foo();
}
export fn entry() void {
foo();
}

// error
// backend=stage2
// target=native
//
// :2:8: error: inline call is recursive

0 comments on commit c959dba

Please sign in to comment.