github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/types/testdata/check/gotos.go (about) 1 // Copyright 2011 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 file is a modified copy of $GOROOT/test/goto.go. 6 7 package gotos 8 9 var ( 10 i, n int 11 x []int 12 c chan int 13 m map[int]int 14 s string 15 ) 16 17 // goto after declaration okay 18 func _() { 19 x := 1 20 goto L 21 L: 22 _ = x 23 } 24 25 // goto before declaration okay 26 func _() { 27 goto L 28 L: 29 x := 1 30 _ = x 31 } 32 33 // goto across declaration not okay 34 func _() { 35 goto L /* ERROR "goto L jumps over variable declaration at line 36" */ 36 x := 1 37 _ = x 38 L: 39 } 40 41 // goto across declaration in inner scope okay 42 func _() { 43 goto L 44 { 45 x := 1 46 _ = x 47 } 48 L: 49 } 50 51 // goto across declaration after inner scope not okay 52 func _() { 53 goto L /* ERROR "goto L jumps over variable declaration at line 58" */ 54 { 55 x := 1 56 _ = x 57 } 58 x := 1 59 _ = x 60 L: 61 } 62 63 // goto across declaration in reverse okay 64 func _() { 65 L: 66 x := 1 67 _ = x 68 goto L 69 } 70 71 func _() { 72 L: L1: 73 x := 1 74 _ = x 75 goto L 76 goto L1 77 } 78 79 // error shows first offending variable 80 func _() { 81 goto L /* ERROR "goto L jumps over variable declaration at line 84" */ 82 x := 1 83 _ = x 84 y := 1 85 _ = y 86 L: 87 } 88 89 // goto not okay even if code path is dead 90 func _() { 91 goto L /* ERROR "goto L jumps over variable declaration" */ 92 x := 1 93 _ = x 94 y := 1 95 _ = y 96 return 97 L: 98 } 99 100 // goto into outer block okay 101 func _() { 102 { 103 goto L 104 } 105 L: 106 } 107 108 func _() { 109 { 110 goto L 111 goto L1 112 } 113 L: L1: 114 } 115 116 // goto backward into outer block okay 117 func _() { 118 L: 119 { 120 goto L 121 } 122 } 123 124 func _() { 125 L: L1: 126 { 127 goto L 128 goto L1 129 } 130 } 131 132 // goto into inner block not okay 133 func _() { 134 goto L /* ERROR "goto L jumps into block" */ 135 { 136 L: 137 } 138 } 139 140 func _() { 141 goto L /* ERROR "goto L jumps into block" */ 142 goto L1 /* ERROR "goto L1 jumps into block" */ 143 { 144 L: L1: 145 } 146 } 147 148 // goto backward into inner block still not okay 149 func _() { 150 { 151 L: 152 } 153 goto L /* ERROR "goto L jumps into block" */ 154 } 155 156 func _() { 157 { 158 L: L1: 159 } 160 goto L /* ERROR "goto L jumps into block" */ 161 goto L1 /* ERROR "goto L1 jumps into block" */ 162 } 163 164 // error shows first (outermost) offending block 165 func _() { 166 goto L /* ERROR "goto L jumps into block" */ 167 { 168 { 169 { 170 L: 171 } 172 } 173 } 174 } 175 176 // error prefers block diagnostic over declaration diagnostic 177 func _() { 178 goto L /* ERROR "goto L jumps into block" */ 179 x := 1 180 _ = x 181 { 182 L: 183 } 184 } 185 186 // many kinds of blocks, all invalid to jump into or among, 187 // but valid to jump out of 188 189 // if 190 191 func _() { 192 L: 193 if true { 194 goto L 195 } 196 } 197 198 func _() { 199 L: 200 if true { 201 goto L 202 } else { 203 } 204 } 205 206 func _() { 207 L: 208 if false { 209 } else { 210 goto L 211 } 212 } 213 214 func _() { 215 goto L /* ERROR "goto L jumps into block" */ 216 if true { 217 L: 218 } 219 } 220 221 func _() { 222 goto L /* ERROR "goto L jumps into block" */ 223 if true { 224 L: 225 } else { 226 } 227 } 228 229 func _() { 230 goto L /* ERROR "goto L jumps into block" */ 231 if true { 232 } else { 233 L: 234 } 235 } 236 237 func _() { 238 if false { 239 L: 240 } else { 241 goto L /* ERROR "goto L jumps into block" */ 242 } 243 } 244 245 func _() { 246 if true { 247 goto L /* ERROR "goto L jumps into block" */ 248 } else { 249 L: 250 } 251 } 252 253 func _() { 254 if true { 255 goto L /* ERROR "goto L jumps into block" */ 256 } else if false { 257 L: 258 } 259 } 260 261 func _() { 262 if true { 263 goto L /* ERROR "goto L jumps into block" */ 264 } else if false { 265 L: 266 } else { 267 } 268 } 269 270 func _() { 271 if true { 272 goto L /* ERROR "goto L jumps into block" */ 273 } else if false { 274 } else { 275 L: 276 } 277 } 278 279 func _() { 280 if true { 281 goto L /* ERROR "goto L jumps into block" */ 282 } else { 283 L: 284 } 285 } 286 287 func _() { 288 if true { 289 L: 290 } else { 291 goto L /* ERROR "goto L jumps into block" */ 292 } 293 } 294 295 // for 296 297 func _() { 298 for { 299 goto L 300 } 301 L: 302 } 303 304 func _() { 305 for { 306 goto L 307 L: 308 } 309 } 310 311 func _() { 312 for { 313 L: 314 } 315 goto L /* ERROR "goto L jumps into block" */ 316 } 317 318 func _() { 319 for { 320 goto L 321 L1: 322 } 323 L: 324 goto L1 /* ERROR "goto L1 jumps into block" */ 325 } 326 327 func _() { 328 for i < n { 329 L: 330 } 331 goto L /* ERROR "goto L jumps into block" */ 332 } 333 334 func _() { 335 for i = 0; i < n; i++ { 336 L: 337 } 338 goto L /* ERROR "goto L jumps into block" */ 339 } 340 341 func _() { 342 for i = range x { 343 L: 344 } 345 goto L /* ERROR "goto L jumps into block" */ 346 } 347 348 func _() { 349 for i = range c { 350 L: 351 } 352 goto L /* ERROR "goto L jumps into block" */ 353 } 354 355 func _() { 356 for i = range m { 357 L: 358 } 359 goto L /* ERROR "goto L jumps into block" */ 360 } 361 362 func _() { 363 for i = range s { 364 L: 365 } 366 goto L /* ERROR "goto L jumps into block" */ 367 } 368 369 // switch 370 371 func _() { 372 L: 373 switch i { 374 case 0: 375 goto L 376 } 377 } 378 379 func _() { 380 L: 381 switch i { 382 case 0: 383 384 default: 385 goto L 386 } 387 } 388 389 func _() { 390 switch i { 391 case 0: 392 393 default: 394 L: 395 goto L 396 } 397 } 398 399 func _() { 400 switch i { 401 case 0: 402 403 default: 404 goto L 405 L: 406 } 407 } 408 409 func _() { 410 switch i { 411 case 0: 412 goto L 413 L: 414 ; 415 default: 416 } 417 } 418 419 func _() { 420 goto L /* ERROR "goto L jumps into block" */ 421 switch i { 422 case 0: 423 L: 424 } 425 } 426 427 func _() { 428 goto L /* ERROR "goto L jumps into block" */ 429 switch i { 430 case 0: 431 L: 432 ; 433 default: 434 } 435 } 436 437 func _() { 438 goto L /* ERROR "goto L jumps into block" */ 439 switch i { 440 case 0: 441 default: 442 L: 443 } 444 } 445 446 func _() { 447 switch i { 448 default: 449 goto L /* ERROR "goto L jumps into block" */ 450 case 0: 451 L: 452 } 453 } 454 455 func _() { 456 switch i { 457 case 0: 458 L: 459 ; 460 default: 461 goto L /* ERROR "goto L jumps into block" */ 462 } 463 } 464 465 // select 466 // different from switch. the statement has no implicit block around it. 467 468 func _() { 469 L: 470 select { 471 case <-c: 472 goto L 473 } 474 } 475 476 func _() { 477 L: 478 select { 479 case c <- 1: 480 481 default: 482 goto L 483 } 484 } 485 486 func _() { 487 select { 488 case <-c: 489 490 default: 491 L: 492 goto L 493 } 494 } 495 496 func _() { 497 select { 498 case c <- 1: 499 500 default: 501 goto L 502 L: 503 } 504 } 505 506 func _() { 507 select { 508 case <-c: 509 goto L 510 L: 511 ; 512 default: 513 } 514 } 515 516 func _() { 517 goto L /* ERROR "goto L jumps into block" */ 518 select { 519 case c <- 1: 520 L: 521 } 522 } 523 524 func _() { 525 goto L /* ERROR "goto L jumps into block" */ 526 select { 527 case c <- 1: 528 L: 529 ; 530 default: 531 } 532 } 533 534 func _() { 535 goto L /* ERROR "goto L jumps into block" */ 536 select { 537 case <-c: 538 default: 539 L: 540 } 541 } 542 543 func _() { 544 select { 545 default: 546 goto L /* ERROR "goto L jumps into block" */ 547 case <-c: 548 L: 549 } 550 } 551 552 func _() { 553 select { 554 case <-c: 555 L: 556 ; 557 default: 558 goto L /* ERROR "goto L jumps into block" */ 559 } 560 }