blob: d660c9ce624aaa69c3e355940c9e891b4643c561 [file] [log] [blame]
Russ Coxd2cc9882012-02-16 23:50:37 -05001// errorcheck
Russ Coxe0a61742011-06-20 14:06:00 -04002
Emmanuel Odeke53fd5222016-04-10 14:32:26 -07003// Copyright 2011 The Go Authors. All rights reserved.
Russ Coxe0a61742011-06-20 14:06:00 -04004// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
Rob Pike83976e32012-02-19 14:28:53 +11007// Verify goto semantics.
8// Does not compile.
9//
Russ Coxe0a61742011-06-20 14:06:00 -040010// Each test is in a separate function just so that if the
11// compiler stops processing after one error, we don't
12// lose other ones.
13
14package main
15
16var (
17 i, n int
18 x []int
19 c chan int
20 m map[int]int
21 s string
22)
23
24// goto after declaration okay
25func _() {
26 x := 1
27 goto L
28L:
29 _ = x
30}
31
32// goto before declaration okay
33func _() {
34 goto L
35L:
36 x := 1
37 _ = x
38}
39
40// goto across declaration not okay
41func _() {
Ian Lance Taylorf1aefc02011-09-20 14:45:54 -070042 goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -070043 x := 1 // GCCGO_ERROR "defined here"
Russ Coxe0a61742011-06-20 14:06:00 -040044 _ = x
45L:
46}
47
48// goto across declaration in inner scope okay
49func _() {
50 goto L
51 {
52 x := 1
53 _ = x
54 }
55L:
56}
57
58// goto across declaration after inner scope not okay
59func _() {
Ian Lance Taylorf1aefc02011-09-20 14:45:54 -070060 goto L // ERROR "goto L jumps over declaration of x at LINE+5|goto jumps over declaration"
Russ Coxe0a61742011-06-20 14:06:00 -040061 {
62 x := 1
63 _ = x
64 }
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -070065 x := 1 // GCCGO_ERROR "defined here"
Russ Coxe0a61742011-06-20 14:06:00 -040066 _ = x
67L:
68}
69
70// goto across declaration in reverse okay
71func _() {
72L:
73 x := 1
74 _ = x
75 goto L
76}
77
78// error shows first offending variable
79func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -070080 goto L // ERROR "goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -070081 x := 1 // GCCGO_ERROR "defined here"
Russ Coxe0a61742011-06-20 14:06:00 -040082 _ = x
83 y := 1
84 _ = y
85L:
86}
87
88// goto not okay even if code path is dead
89func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -070090 goto L // ERROR "goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -070091 x := 1 // GCCGO_ERROR "defined here"
Russ Coxe0a61742011-06-20 14:06:00 -040092 _ = x
93 y := 1
94 _ = y
95 return
96L:
97}
98
99// goto into outer block okay
100func _() {
101 {
102 goto L
103 }
104L:
105}
106
107// goto backward into outer block okay
108func _() {
109L:
110 {
111 goto L
112 }
113}
114
115// goto into inner block not okay
116func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700117 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700118 { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400119 L:
120 }
121}
122
123// goto backward into inner block still not okay
124func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700125 { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400126 L:
127 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700128 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400129}
130
131// error shows first (outermost) offending block
132func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700133 goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400134 {
135 {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700136 { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400137 L:
138 }
139 }
140 }
141}
142
143// error prefers block diagnostic over declaration diagnostic
144func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700145 goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400146 x := 1
147 _ = x
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700148 { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400149 L:
150 }
151}
152
153// many kinds of blocks, all invalid to jump into or among,
154// but valid to jump out of
155
156// if
157
158func _() {
159L:
160 if true {
161 goto L
162 }
163}
164
165func _() {
166L:
167 if true {
168 goto L
169 } else {
170 }
171}
172
173func _() {
174L:
175 if false {
176 } else {
177 goto L
178 }
179}
180
181func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700182 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700183 if true { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400184 L:
185 }
186}
187
188func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700189 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700190 if true { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400191 L:
192 } else {
193 }
194}
195
196func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700197 goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400198 if true {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700199 } else { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400200 L:
201 }
202}
203
204func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700205 if false { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400206 L:
207 } else {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700208 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400209 }
210}
211
212func _() {
213 if true {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700214 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700215 } else { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400216 L:
217 }
218}
219
220func _() {
221 if true {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700222 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700223 } else if false { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400224 L:
225 }
226}
227
228func _() {
229 if true {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700230 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700231 } else if false { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400232 L:
233 } else {
234 }
235}
236
237func _() {
238 // This one is tricky. There is an implicit scope
239 // starting at the second if statement, and it contains
240 // the final else, so the outermost offending scope
241 // really is LINE+1 (like in the previous test),
242 // even though it looks like it might be LINE+3 instead.
243 if true {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700244 goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400245 } else if false {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700246 } else { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400247 L:
248 }
249}
250
251/* Want to enable these tests but gofmt mangles them. Issue 1972.
252
253func _() {
254 // This one is okay, because the else is in the
255 // implicit whole-if block and has no inner block
256 // (no { }) around it.
257 if true {
258 goto L
259 } else
260 L:
261}
262
263func _() {
264 // Still not okay.
Ian Lance Taylorf1aefc02011-09-20 14:45:54 -0700265 if true { //// GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400266 L:
267 } else
Ian Lance Taylorf1aefc02011-09-20 14:45:54 -0700268 goto L //// ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400269}
270
271*/
272
273// for
274
275func _() {
276 for {
277 goto L
278 }
279L:
280}
281
282func _() {
283 for {
284 goto L
285 L:
286 }
287}
288
289func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700290 for { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400291 L:
292 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700293 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400294}
295
296func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700297 for { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400298 goto L
299 L1:
300 }
301L:
Robert Griesemerbb70f512017-04-18 17:16:54 -0700302 goto L1 // ERROR "goto L1 jumps into block starting at LINE-5|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400303}
304
305func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700306 for i < n { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400307 L:
308 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700309 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400310}
311
312func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700313 for i = 0; i < n; i++ { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400314 L:
315 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700316 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400317}
318
319func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700320 for i = range x { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400321 L:
322 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700323 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400324}
325
326func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700327 for i = range c { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400328 L:
329 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700330 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400331}
332
333func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700334 for i = range m { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400335 L:
336 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700337 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400338}
339
340func _() {
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700341 for i = range s { // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400342 L:
343 }
Robert Griesemerbb70f512017-04-18 17:16:54 -0700344 goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400345}
346
347// switch
348
349func _() {
350L:
351 switch i {
352 case 0:
353 goto L
354 }
355}
356
357func _() {
358L:
359 switch i {
360 case 0:
361
362 default:
363 goto L
364 }
365}
366
367func _() {
368 switch i {
369 case 0:
370
371 default:
372 L:
373 goto L
374 }
375}
376
377func _() {
378 switch i {
379 case 0:
380
381 default:
382 goto L
383 L:
384 }
385}
386
387func _() {
388 switch i {
389 case 0:
390 goto L
391 L:
392 ;
393 default:
394 }
395}
396
397func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700398 goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400399 switch i {
400 case 0:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700401 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400402 }
403}
404
405func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700406 goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400407 switch i {
408 case 0:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700409 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400410 ;
411 default:
412 }
413}
414
415func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700416 goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400417 switch i {
418 case 0:
419 default:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700420 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400421 }
422}
423
424func _() {
425 switch i {
426 default:
Robert Griesemerbb70f512017-04-18 17:16:54 -0700427 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400428 case 0:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700429 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400430 }
431}
432
433func _() {
434 switch i {
435 case 0:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700436 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400437 ;
438 default:
Robert Griesemerbb70f512017-04-18 17:16:54 -0700439 goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400440 }
441}
442
443// select
444// different from switch. the statement has no implicit block around it.
445
446func _() {
447L:
448 select {
449 case <-c:
450 goto L
451 }
452}
453
454func _() {
455L:
456 select {
457 case c <- 1:
458
459 default:
460 goto L
461 }
462}
463
464func _() {
465 select {
466 case <-c:
467
468 default:
469 L:
470 goto L
471 }
472}
473
474func _() {
475 select {
476 case c <- 1:
477
478 default:
479 goto L
480 L:
481 }
482}
483
484func _() {
485 select {
486 case <-c:
487 goto L
488 L:
489 ;
490 default:
491 }
492}
493
494func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700495 goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400496 select {
497 case c <- 1:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700498 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400499 }
500}
501
502func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700503 goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400504 select {
505 case c <- 1:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700506 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400507 ;
508 default:
509 }
510}
511
512func _() {
Robert Griesemerbb70f512017-04-18 17:16:54 -0700513 goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400514 select {
515 case <-c:
516 default:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700517 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400518 }
519}
520
521func _() {
522 select {
523 default:
Robert Griesemerbb70f512017-04-18 17:16:54 -0700524 goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400525 case <-c:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700526 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400527 }
528}
529
530func _() {
531 select {
532 case <-c:
Josh Bleecher Snyderffbf2092015-07-20 13:00:28 -0700533 L: // GCCGO_ERROR "block starts here"
Russ Coxe0a61742011-06-20 14:06:00 -0400534 ;
535 default:
Robert Griesemerbb70f512017-04-18 17:16:54 -0700536 goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
Russ Coxe0a61742011-06-20 14:06:00 -0400537 }
538}