blob: 069a94bbbf42f930a972e260702b942ef61bb665 [file] [log] [blame]
// Copyright 2011 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.
// This file is a modified copy of $GOROOT/test/goto.go.
package gotos
var (
i, n int
x []int
c chan int
m map[int]int
s string
)
// goto after declaration okay
func _() {
x := 1
goto L
L:
_ = x
}
// goto before declaration okay
func _() {
goto L
L:
x := 1
_ = x
}
// goto across declaration not okay
func _() {
goto L /* ERROR "goto L jumps over variable declaration at line 36" */
x := 1
_ = x
L:
}
// goto across declaration in inner scope okay
func _() {
goto L
{
x := 1
_ = x
}
L:
}
// goto across declaration after inner scope not okay
func _() {
goto L /* ERROR "goto L jumps over variable declaration at line 58" */
{
x := 1
_ = x
}
x := 1
_ = x
L:
}
// goto across declaration in reverse okay
func _() {
L:
x := 1
_ = x
goto L
}
func _() {
L: L1:
x := 1
_ = x
goto L
goto L1
}
// error shows first offending variable
func _() {
goto L /* ERROR "goto L jumps over variable declaration at line 84" */
x := 1
_ = x
y := 1
_ = y
L:
}
// goto not okay even if code path is dead
func _() {
goto L /* ERROR "goto L jumps over variable declaration" */
x := 1
_ = x
y := 1
_ = y
return
L:
}
// goto into outer block okay
func _() {
{
goto L
}
L:
}
func _() {
{
goto L
goto L1
}
L: L1:
}
// goto backward into outer block okay
func _() {
L:
{
goto L
}
}
func _() {
L: L1:
{
goto L
goto L1
}
}
// goto into inner block not okay
func _() {
goto L /* ERROR "goto L jumps into block" */
{
L:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
goto L1 /* ERROR "goto L1 jumps into block" */
{
L: L1:
}
}
// goto backward into inner block still not okay
func _() {
{
L:
}
goto L /* ERROR "goto L jumps into block" */
}
func _() {
{
L: L1:
}
goto L /* ERROR "goto L jumps into block" */
goto L1 /* ERROR "goto L1 jumps into block" */
}
// error shows first (outermost) offending block
func _() {
goto L /* ERROR "goto L jumps into block" */
{
{
{
L:
}
}
}
}
// error prefers block diagnostic over declaration diagnostic
func _() {
goto L /* ERROR "goto L jumps into block" */
x := 1
_ = x
{
L:
}
}
// many kinds of blocks, all invalid to jump into or among,
// but valid to jump out of
// if
func _() {
L:
if true {
goto L
}
}
func _() {
L:
if true {
goto L
} else {
}
}
func _() {
L:
if false {
} else {
goto L
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
if true {
L:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
if true {
L:
} else {
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
if true {
} else {
L:
}
}
func _() {
if false {
L:
} else {
goto L /* ERROR "goto L jumps into block" */
}
}
func _() {
if true {
goto L /* ERROR "goto L jumps into block" */
} else {
L:
}
}
func _() {
if true {
goto L /* ERROR "goto L jumps into block" */
} else if false {
L:
}
}
func _() {
if true {
goto L /* ERROR "goto L jumps into block" */
} else if false {
L:
} else {
}
}
func _() {
if true {
goto L /* ERROR "goto L jumps into block" */
} else if false {
} else {
L:
}
}
func _() {
if true {
goto L /* ERROR "goto L jumps into block" */
} else {
L:
}
}
func _() {
if true {
L:
} else {
goto L /* ERROR "goto L jumps into block" */
}
}
// for
func _() {
for {
goto L
}
L:
}
func _() {
for {
goto L
L:
}
}
func _() {
for {
L:
}
goto L /* ERROR "goto L jumps into block" */
}
func _() {
for {
goto L
L1:
}
L:
goto L1 /* ERROR "goto L1 jumps into block" */
}
func _() {
for i < n {
L:
}
goto L /* ERROR "goto L jumps into block" */
}
func _() {
for i = 0; i < n; i++ {
L:
}
goto L /* ERROR "goto L jumps into block" */
}
func _() {
for i = range x {
L:
}
goto L /* ERROR "goto L jumps into block" */
}
func _() {
for i = range c {
L:
}
goto L /* ERROR "goto L jumps into block" */
}
func _() {
for i = range m {
L:
}
goto L /* ERROR "goto L jumps into block" */
}
func _() {
for i = range s {
L:
}
goto L /* ERROR "goto L jumps into block" */
}
// switch
func _() {
L:
switch i {
case 0:
goto L
}
}
func _() {
L:
switch i {
case 0:
default:
goto L
}
}
func _() {
switch i {
case 0:
default:
L:
goto L
}
}
func _() {
switch i {
case 0:
default:
goto L
L:
}
}
func _() {
switch i {
case 0:
goto L
L:
;
default:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
switch i {
case 0:
L:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
switch i {
case 0:
L:
;
default:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
switch i {
case 0:
default:
L:
}
}
func _() {
switch i {
default:
goto L /* ERROR "goto L jumps into block" */
case 0:
L:
}
}
func _() {
switch i {
case 0:
L:
;
default:
goto L /* ERROR "goto L jumps into block" */
}
}
// select
// different from switch. the statement has no implicit block around it.
func _() {
L:
select {
case <-c:
goto L
}
}
func _() {
L:
select {
case c <- 1:
default:
goto L
}
}
func _() {
select {
case <-c:
default:
L:
goto L
}
}
func _() {
select {
case c <- 1:
default:
goto L
L:
}
}
func _() {
select {
case <-c:
goto L
L:
;
default:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
select {
case c <- 1:
L:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
select {
case c <- 1:
L:
;
default:
}
}
func _() {
goto L /* ERROR "goto L jumps into block" */
select {
case <-c:
default:
L:
}
}
func _() {
select {
default:
goto L /* ERROR "goto L jumps into block" */
case <-c:
L:
}
}
func _() {
select {
case <-c:
L:
;
default:
goto L /* ERROR "goto L jumps into block" */
}
}