Commit 65d3723968
Changed files (4)
lib/std/target.zig
@@ -1440,6 +1440,16 @@ pub const Target = struct {
return !self.cpu.arch.isWasm();
}
+ pub fn supportsTailCall(self: Target) bool {
+ switch (self.cpu.arch) {
+ .wasm32, .wasm64 => return wasm.featureSetHas(self.cpu.features, .tail_call),
+ // TODO these might not be true but LLVM doesn't seem to be able to handle them
+ .mips, .mipsel, .mips64, .mips64el => return false,
+ .powerpc, .powerpcle, .powerpc64, .powerpc64le => return false,
+ else => return true,
+ }
+ }
+
pub const FloatAbi = enum {
hard,
soft,
src/Sema.zig
@@ -6160,6 +6160,10 @@ fn analyzeCall(
}
fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {
+ const target = sema.mod.getTarget();
+ if (!target.supportsTailCall()) {
+ return sema.fail(block, call_src, "unable to perform tail call: target does not support tail calls", .{});
+ }
const func_decl = sema.mod.declPtr(sema.owner_func.?.owner_decl);
if (!func_ty.eql(func_decl.ty, sema.mod)) {
return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{
test/behavior/call.zig
@@ -270,6 +270,8 @@ test "forced tail call" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (comptime !builtin.target.supportsTailCall()) return error.SkipZigTest;
+
const S = struct {
fn fibonacciTailInternal(n: u16, a: u16, b: u16) u16 {
if (n == 0) return a;
@@ -296,6 +298,8 @@ test "inline call preserves tail call" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (comptime !builtin.target.supportsTailCall()) return error.SkipZigTest;
+
const max = std.math.maxInt(u16);
const S = struct {
var a: u16 = 0;
test/cases/taill_call_noreturn.zig
@@ -15,4 +15,4 @@ pub fn main() void {
// run
// backend=llvm
-// target=native
+// target=x86_64-linux,x86_64-macos,aarch64-linux,aarch64-macos