File: defererrcheck.go

package info (click to toggle)
golang-1.24 1.24.4-3
  • links: PTS, VCS
  • area: main
  • in suites: experimental, sid
  • size: 167,820 kB
  • sloc: asm: 154,901; ansic: 7,009; sh: 2,267; javascript: 1,705; perl: 1,052; python: 421; makefile: 110; cpp: 39; f90: 8; awk: 7; objc: 4
file content (140 lines) | stat: -rw-r--r-- 2,454 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// 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("")
	}
}