| author | |
| committer | |
| log | 65d37239682b6418b6dd25f07187ae99088e67f0 |
| tree | b8ea48551a149e889247f07a09353eb452ff4e1f |
| parent | c558de6655e2e9b72c5733b2d477ff18520d1c6b |
4 files changed, 19 insertions(+), 1 deletions(-)
lib/std/target.zig+10| ... | ... | @@ -1440,6 +1440,16 @@ pub const Target = struct { |
| 1440 | 1440 | return !self.cpu.arch.isWasm(); |
| 1441 | 1441 | } |
| 1442 | 1442 | |
| 1443 | pub fn supportsTailCall(self: Target) bool { | |
| 1444 | switch (self.cpu.arch) { | |
| 1445 | .wasm32, .wasm64 => return wasm.featureSetHas(self.cpu.features, .tail_call), | |
| 1446 | // TODO these might not be true but LLVM doesn't seem to be able to handle them | |
| 1447 | .mips, .mipsel, .mips64, .mips64el => return false, | |
| 1448 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => return false, | |
| 1449 | else => return true, | |
| 1450 | } | |
| 1451 | } | |
| 1452 | ||
| 1443 | 1453 | pub const FloatAbi = enum { |
| 1444 | 1454 | hard, |
| 1445 | 1455 | soft, |
src/Sema.zig+4| ... | ... | @@ -6160,6 +6160,10 @@ fn analyzeCall( |
| 6160 | 6160 | } |
| 6161 | 6161 | |
| 6162 | 6162 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { |
| 6163 | const target = sema.mod.getTarget(); | |
| 6164 | if (!target.supportsTailCall()) { | |
| 6165 | return sema.fail(block, call_src, "unable to perform tail call: target does not support tail calls", .{}); | |
| 6166 | } | |
| 6163 | 6167 | const func_decl = sema.mod.declPtr(sema.owner_func.?.owner_decl); |
| 6164 | 6168 | if (!func_ty.eql(func_decl.ty, sema.mod)) { |
| 6165 | 6169 | 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+4| ... | ... | @@ -270,6 +270,8 @@ test "forced tail call" { |
| 270 | 270 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 271 | 271 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 272 | 272 | |
| 273 | if (comptime !builtin.target.supportsTailCall()) return error.SkipZigTest; | |
| 274 | ||
| 273 | 275 | const S = struct { |
| 274 | 276 | fn fibonacciTailInternal(n: u16, a: u16, b: u16) u16 { |
| 275 | 277 | if (n == 0) return a; |
| ... | ... | @@ -296,6 +298,8 @@ test "inline call preserves tail call" { |
| 296 | 298 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 297 | 299 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 298 | 300 | |
| 301 | if (comptime !builtin.target.supportsTailCall()) return error.SkipZigTest; | |
| 302 | ||
| 299 | 303 | const max = std.math.maxInt(u16); |
| 300 | 304 | const S = struct { |
| 301 | 305 | var a: u16 = 0; |
test/cases/taill_call_noreturn.zig+1-1| ... | ... | @@ -15,4 +15,4 @@ pub fn main() void { |
| 15 | 15 | |
| 16 | 16 | // run |
| 17 | 17 | // backend=llvm |
| 18 | // target=native | |
| 18 | // target=x86_64-linux,x86_64-macos,aarch64-linux,aarch64-macos |