blob: 4997241588372b203513249c96f702038620c64e [file]
// TARGET_BACKEND: WASM
// Without ENABLE_TAIL_CALLS (the default), calls in tail position must be emitted as
// plain calls. Tail-call emission preserves program results, so only these
// instruction-level checks can detect an accidentally enabled default.
// Direct static tail call must stay a plain call
// WASM_CHECK_INSTRUCTION_NOT_IN_FUNCTION: instruction=return_call inFunction=staticTailCaller
// Virtual dispatch tail call must stay a plain call_ref
// WASM_CHECK_INSTRUCTION_NOT_IN_FUNCTION: instruction=return_call_ref inFunction=virtualTailCaller
// Interface dispatch tail call must stay a plain call_ref
// WASM_CHECK_INSTRUCTION_NOT_IN_FUNCTION: instruction=return_call_ref inFunction=interfaceTailCaller
fun staticCallee(x: Int): Int = x + 1
fun staticTailCaller(x: Int): Int = staticCallee(x)
abstract class VirtualBase {
abstract fun action(x: Int): Int
}
class VirtualImpl : VirtualBase() {
override fun action(x: Int): Int = x * 2
}
fun virtualTailCaller(b: VirtualBase, x: Int): Int = b.action(x)
interface InterfaceBase {
fun ping(x: Int): Int
}
class InterfaceImpl : InterfaceBase {
override fun ping(x: Int): Int = x + 7
}
fun interfaceTailCaller(b: InterfaceBase, x: Int): Int = b.ping(x)
fun box(): String {
if (staticTailCaller(41) != 42) return "fail static"
if (virtualTailCaller(VirtualImpl(), 21) != 42) return "fail virtual"
if (interfaceTailCaller(InterfaceImpl(), 35) != 42) return "fail interface"
return "OK"
}