| // errorcheck -0 -l -d=defer |
| |
| // Copyright 2019 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // check that open-coded defers are used in expected situations |
| |
| package main |
| |
| import "fmt" |
| |
| var glob = 3 |
| |
| func f1() { |
| |
| for i := 0; i < 10; i++ { |
| fmt.Println("loop") |
| } |
| defer func() { // ERROR "open-coded defer" |
| fmt.Println("defer") |
| }() |
| } |
| |
| func f2() { |
| for { |
| defer func() { // ERROR "heap-allocated defer" |
| fmt.Println("defer1") |
| }() |
| if glob > 2 { |
| break |
| } |
| } |
| defer func() { // ERROR "stack-allocated defer" |
| fmt.Println("defer2") |
| }() |
| } |
| |
| func f3() { |
| defer func() { // ERROR "stack-allocated defer" |
| fmt.Println("defer2") |
| }() |
| for { |
| defer func() { // ERROR "heap-allocated defer" |
| fmt.Println("defer1") |
| }() |
| if glob > 2 { |
| break |
| } |
| } |
| } |
| |
| func f4() { |
| defer func() { // ERROR "open-coded defer" |
| fmt.Println("defer") |
| }() |
| label: |
| fmt.Println("goto loop") |
| if glob > 2 { |
| goto label |
| } |
| } |
| |
| func f5() { |
| label: |
| fmt.Println("goto loop") |
| defer func() { // ERROR "heap-allocated defer" |
| fmt.Println("defer") |
| }() |
| if glob > 2 { |
| goto label |
| } |
| } |
| |
| func f6() { |
| label: |
| fmt.Println("goto loop") |
| if glob > 2 { |
| goto label |
| } |
| // The current analysis doesn't end a backward goto loop, so this defer is |
| // considered to be inside a loop |
| defer func() { // ERROR "heap-allocated defer" |
| fmt.Println("defer") |
| }() |
| } |
| |
| // Test for function with too many exits, which will disable open-coded defer |
| // even though the number of defer statements is not greater than 8. |
| func f7() { |
| defer println(1) // ERROR "open-coded defer" |
| defer println(1) // ERROR "open-coded defer" |
| defer println(1) // ERROR "open-coded defer" |
| defer println(1) // ERROR "open-coded defer" |
| |
| switch glob { |
| case 1: |
| return |
| case 2: |
| return |
| case 3: |
| return |
| } |
| } |
| |
| func f8() { |
| defer println(1) // ERROR "stack-allocated defer" |
| defer println(1) // ERROR "stack-allocated defer" |
| defer println(1) // ERROR "stack-allocated defer" |
| defer println(1) // ERROR "stack-allocated defer" |
| |
| switch glob { |
| case 1: |
| return |
| case 2: |
| return |
| case 3: |
| return |
| case 4: |
| return |
| } |
| } |
| |
| func f9() { |
| defer println(1) // ERROR "open-coded defer" |
| defer println(1) // ERROR "open-coded defer" |
| defer println(1) // ERROR "open-coded defer" |
| defer println(1) // ERROR "open-coded defer" |
| |
| switch glob { |
| case 1: |
| return |
| case 2: |
| return |
| case 3: |
| return |
| case 4: |
| panic("") |
| } |
| } |