mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
Sema: check that target supports tail calls
This commit is contained in:
parent
c558de6655
commit
65d3723968
@ -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,
|
||||
|
||||
@ -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 '{}'", .{
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -15,4 +15,4 @@ pub fn main() void {
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// target=native
|
||||
// target=x86_64-linux,x86_64-macos,aarch64-linux,aarch64-macos
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user