blob: d25662d568dfeda9efc52b8ea73b3db1329c9200 [file] [edit]
Void tail-call inlining test cases.
1. a0: deeply nested bare blocks ending in return.
2. a1: call in switch case, with return after the switch statement.
3. a2: complex nested hierarchy (if -> switch -> block) ending at return.
4. a3: multiple stacked labels before return.
5. a4: call inside else-if branch with explicit return.
6. a5: call inside for loop (must literalize, loop repeats).
7. a6: trailing code after block (must literalize).
8. a7: last statement of if at function end (implicit return).
9. a8: last statement of else at function end (implicit return).
10. a9: type switch case, with return after the type switch.
11. a10: fallthrough after the call (must literalize).
12. a11: call in select default, with return after the select.
13. a12: stacked labels on the return that follows the call.
14. a13: explicit bare return, func f() { defer ...; return }.
-- go.mod --
module testdata
go 1.20
-- a/pkg.go --
package a
func cleanup() {
defer println("done")
println("cleaning")
}
-- a/a0.go --
package a
func _() {
{
{
cleanup() //@ inline(re"cleanup", nestedBlocks)
}
}
return
}
-- nestedBlocks --
package a
func _() {
{
{
defer println("done")
println("cleaning") //@ inline(re"cleanup", nestedBlocks)
}
}
return
}
-- a/a1.go --
package a
func _(x int) {
switch x {
case 1:
cleanup() //@ inline(re"cleanup", switchThenReturn)
default:
println("default")
}
return
}
-- switchThenReturn --
package a
func _(x int) {
switch x {
case 1:
defer println("done")
println("cleaning") //@ inline(re"cleanup", switchThenReturn)
default:
println("default")
}
return
}
-- a/a2.go --
package a
func _(x int, cond bool) {
if cond {
switch x {
case 1:
{
cleanup() //@ inline(re"cleanup", ifSwitchBlock)
}
}
}
return
}
-- ifSwitchBlock --
package a
func _(x int, cond bool) {
if cond {
switch x {
case 1:
{
defer println("done")
println("cleaning") //@ inline(re"cleanup", ifSwitchBlock)
}
}
}
return
}
-- a/a3.go --
package a
func _() {
label1:
label2:
cleanup() //@ inline(re"cleanup", stackedLabels)
return
}
-- stackedLabels --
package a
func _() {
label1:
label2:
{
defer println("done")
println("cleaning")
} //@ inline(re"cleanup", stackedLabels)
return
}
-- a/a4.go --
package a
func _(a, b int) {
if a > 0 {
println("a")
} else if b > 0 {
cleanup() //@ inline(re"cleanup", elseIfReturn)
return
}
println("after")
}
-- elseIfReturn --
package a
func _(a, b int) {
if a > 0 {
println("a")
} else if b > 0 {
defer println("done")
println("cleaning") //@ inline(re"cleanup", elseIfReturn)
return
}
println("after")
}
-- a/a5.go --
package a
func _() {
for i := 0; i < 2; i++ {
cleanup() //@ inline(re"cleanup", inLoop)
}
return
}
-- inLoop --
package a
func _() {
for i := 0; i < 2; i++ {
func() { defer println("done"); println("cleaning") }() //@ inline(re"cleanup", inLoop)
}
return
}
-- a/a6.go --
package a
func _() {
{
cleanup() //@ inline(re"cleanup", trailingCode)
}
println("not tail")
return
}
-- trailingCode --
package a
func _() {
{
func() { defer println("done"); println("cleaning") }() //@ inline(re"cleanup", trailingCode)
}
println("not tail")
return
}
-- a/a7.go --
package a
func _(cond bool) {
if cond {
cleanup() //@ inline(re"cleanup", lastInIf)
} else {
println("else")
}
}
-- lastInIf --
package a
func _(cond bool) {
if cond {
defer println("done")
println("cleaning") //@ inline(re"cleanup", lastInIf)
} else {
println("else")
}
}
-- a/a8.go --
package a
func _(cond bool) {
if cond {
println("then")
} else {
cleanup() //@ inline(re"cleanup", lastInElse)
}
}
-- lastInElse --
package a
func _(cond bool) {
if cond {
println("then")
} else {
defer println("done")
println("cleaning") //@ inline(re"cleanup", lastInElse)
}
}
-- a/a9.go --
package a
func _(x any) {
switch x.(type) {
case int:
cleanup() //@ inline(re"cleanup", typeSwitchThenReturn)
default:
println("default")
}
return
}
-- typeSwitchThenReturn --
package a
func _(x any) {
switch x.(type) {
case int:
defer println("done")
println("cleaning") //@ inline(re"cleanup", typeSwitchThenReturn)
default:
println("default")
}
return
}
-- a/a10.go --
package a
func _(x int) {
switch x {
case 1:
cleanup() //@ inline(re"cleanup", fallthroughAfter)
fallthrough
default:
println("default")
}
return
}
-- fallthroughAfter --
package a
func _(x int) {
switch x {
case 1:
func() { defer println("done"); println("cleaning") }() //@ inline(re"cleanup", fallthroughAfter)
fallthrough
default:
println("default")
}
return
}
-- a/a11.go --
package a
func _() {
select {
default:
cleanup() //@ inline(re"cleanup", selectThenReturn)
}
return
}
-- selectThenReturn --
package a
func _() {
select {
default:
defer println("done")
println("cleaning") //@ inline(re"cleanup", selectThenReturn)
}
return
}
-- a/a12.go --
package a
func _() {
cleanup() //@ inline(re"cleanup", labeledReturn)
done:
return
}
-- labeledReturn --
package a
func _() {
{
defer println("done")
println("cleaning")
} //@ inline(re"cleanup", labeledReturn)
done:
return
}
-- a/a13.go --
package a
func f() {
justDefer() //@ inline(re"justDefer", explicitBareReturn)
return
}
func justDefer() {
defer println("done")
}
-- explicitBareReturn --
package a
func f() {
defer println("done") //@ inline(re"justDefer", explicitBareReturn)
return
}
func justDefer() {
defer println("done")
}