1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This program is processed by the cover command, and then testAll is called.
6// The test driver in main.go can then compare the coverage statistics with expectation.
7
8// The word LINE is replaced by the line number in this file. When the file is executed,
9// the coverage processing has changed the line numbers, so we can't use runtime.Caller.
10
11package main
12
13import _ "unsafe" // for go:linkname
14
15//go:linkname some_name some_name
16var some_name int
17
18const anything = 1e9 // Just some unlikely value that means "we got here, don't care how often"
19
20func testAll() {
21	testSimple()
22	testBlockRun()
23	testIf()
24	testFor()
25	testRange()
26	testSwitch()
27	testTypeSwitch()
28	testSelect1()
29	testSelect2()
30	testPanic()
31	testEmptySwitches()
32	testFunctionLiteral()
33	testGoto()
34}
35
36// The indexes of the counters in testPanic are known to main.go
37const panicIndex = 3
38
39// This test appears first because the index of its counters is known to main.go
40func testPanic() {
41	defer func() {
42		recover()
43	}()
44	check(LINE, 1)
45	panic("should not get next line")
46	check(LINE, 0) // this is GoCover.Count[panicIndex]
47	// The next counter is in testSimple and it will be non-zero.
48	// If the panic above does not trigger a counter, the test will fail
49	// because GoCover.Count[panicIndex] will be the one in testSimple.
50}
51
52func testSimple() {
53	check(LINE, 1)
54}
55
56func testIf() {
57	if true {
58		check(LINE, 1)
59	} else {
60		check(LINE, 0)
61	}
62	if false {
63		check(LINE, 0)
64	} else {
65		check(LINE, 1)
66	}
67	for i := 0; i < 3; i++ {
68		if checkVal(LINE, 3, i) <= 2 {
69			check(LINE, 3)
70		}
71		if checkVal(LINE, 3, i) <= 1 {
72			check(LINE, 2)
73		}
74		if checkVal(LINE, 3, i) <= 0 {
75			check(LINE, 1)
76		}
77	}
78	for i := 0; i < 3; i++ {
79		if checkVal(LINE, 3, i) <= 1 {
80			check(LINE, 2)
81		} else {
82			check(LINE, 1)
83		}
84	}
85	for i := 0; i < 3; i++ {
86		if checkVal(LINE, 3, i) <= 0 {
87			check(LINE, 1)
88		} else if checkVal(LINE, 2, i) <= 1 {
89			check(LINE, 1)
90		} else if checkVal(LINE, 1, i) <= 2 {
91			check(LINE, 1)
92		} else if checkVal(LINE, 0, i) <= 3 {
93			check(LINE, 0)
94		}
95	}
96	if func(a, b int) bool { return a < b }(3, 4) {
97		check(LINE, 1)
98	}
99}
100
101func testFor() {
102	for i := 0; i < 10; func() { i++; check(LINE, 10) }() {
103		check(LINE, 10)
104	}
105}
106
107func testRange() {
108	for _, f := range []func(){
109		func() { check(LINE, 1) },
110	} {
111		f()
112		check(LINE, 1)
113	}
114}
115
116func testBlockRun() {
117	check(LINE, 1)
118	{
119		check(LINE, 1)
120	}
121	{
122		check(LINE, 1)
123	}
124	check(LINE, 1)
125	{
126		check(LINE, 1)
127	}
128	{
129		check(LINE, 1)
130	}
131	check(LINE, 1)
132}
133
134func testSwitch() {
135	for i := 0; i < 5; func() { i++; check(LINE, 5) }() {
136		goto label2
137	label1:
138		goto label1
139	label2:
140		switch i {
141		case 0:
142			check(LINE, 1)
143		case 1:
144			check(LINE, 1)
145		case 2:
146			check(LINE, 1)
147		default:
148			check(LINE, 2)
149		}
150	}
151}
152
153func testTypeSwitch() {
154	var x = []any{1, 2.0, "hi"}
155	for _, v := range x {
156		switch func() { check(LINE, 3) }(); v.(type) {
157		case int:
158			check(LINE, 1)
159		case float64:
160			check(LINE, 1)
161		case string:
162			check(LINE, 1)
163		case complex128:
164			check(LINE, 0)
165		default:
166			check(LINE, 0)
167		}
168	}
169}
170
171func testSelect1() {
172	c := make(chan int)
173	go func() {
174		for i := 0; i < 1000; i++ {
175			c <- i
176		}
177	}()
178	for {
179		select {
180		case <-c:
181			check(LINE, anything)
182		case <-c:
183			check(LINE, anything)
184		default:
185			check(LINE, 1)
186			return
187		}
188	}
189}
190
191func testSelect2() {
192	c1 := make(chan int, 1000)
193	c2 := make(chan int, 1000)
194	for i := 0; i < 1000; i++ {
195		c1 <- i
196		c2 <- i
197	}
198	for {
199		select {
200		case <-c1:
201			check(LINE, 1000)
202		case <-c2:
203			check(LINE, 1000)
204		default:
205			check(LINE, 1)
206			return
207		}
208	}
209}
210
211// Empty control statements created syntax errors. This function
212// is here just to be sure that those are handled correctly now.
213func testEmptySwitches() {
214	check(LINE, 1)
215	switch 3 {
216	}
217	check(LINE, 1)
218	switch i := (any)(3).(int); i {
219	}
220	check(LINE, 1)
221	c := make(chan int)
222	go func() {
223		check(LINE, 1)
224		c <- 1
225		select {}
226	}()
227	<-c
228	check(LINE, 1)
229}
230
231func testFunctionLiteral() {
232	a := func(f func()) error {
233		f()
234		f()
235		return nil
236	}
237
238	b := func(f func()) bool {
239		f()
240		f()
241		return true
242	}
243
244	check(LINE, 1)
245	a(func() {
246		check(LINE, 2)
247	})
248
249	if err := a(func() {
250		check(LINE, 2)
251	}); err != nil {
252	}
253
254	switch b(func() {
255		check(LINE, 2)
256	}) {
257	}
258
259	x := 2
260	switch x {
261	case func() int { check(LINE, 1); return 1 }():
262		check(LINE, 0)
263		panic("2=1")
264	case func() int { check(LINE, 1); return 2 }():
265		check(LINE, 1)
266	case func() int { check(LINE, 0); return 3 }():
267		check(LINE, 0)
268		panic("2=3")
269	}
270}
271
272func testGoto() {
273	for i := 0; i < 2; i++ {
274		if i == 0 {
275			goto Label
276		}
277		check(LINE, 1)
278	Label:
279		check(LINE, 2)
280	}
281	// Now test that we don't inject empty statements
282	// between a label and a loop.
283loop:
284	for {
285		check(LINE, 1)
286		break loop
287	}
288}
289
290// This comment didn't appear in generated go code.
291func haha() {
292	// Needed for cover to add counter increment here.
293	_ = 42
294}
295
296// Some someFunction.
297//
298//go:nosplit
299func someFunction() {
300}
301