diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /test/return.go | |
parent | Initial commit. (diff) | |
download | golang-1.16-upstream.tar.xz golang-1.16-upstream.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/return.go')
-rw-r--r-- | test/return.go | 2821 |
1 files changed, 2821 insertions, 0 deletions
diff --git a/test/return.go b/test/return.go new file mode 100644 index 0000000..95f94b9 --- /dev/null +++ b/test/return.go @@ -0,0 +1,2821 @@ +// errorcheck + +// Copyright 2013 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. + +// Test compiler diagnosis of function missing return statements. +// See issue 65 and golang.org/s/go11return. + +package p + +type T int + +var x interface{} +var c chan int + +func external() int // ok + +func _() int { +} // ERROR "missing return" + +func _() int { + print(1) +} // ERROR "missing return" + +// return is okay +func _() int { + print(1) + return 2 +} + +// goto is okay +func _() int { +L: + print(1) + goto L +} + +// panic is okay +func _() int { + print(1) + panic(2) +} + +// but only builtin panic +func _() int { + var panic = func(int) {} + print(1) + panic(2) +} // ERROR "missing return" + +// block ending in terminating statement is okay +func _() int { + { + print(1) + return 2 + } +} + +// block ending in terminating statement is okay +func _() int { +L: + { + print(1) + goto L + } +} + +// block ending in terminating statement is okay +func _() int { + print(1) + { + panic(2) + } +} + +// adding more code - even though it is dead - now requires a return + +func _() int { + print(1) + return 2 + print(3) +} // ERROR "missing return" + +func _() int { +L: + print(1) + goto L + print(3) +} // ERROR "missing return" + +func _() int { + print(1) + panic(2) + print(3) +} // ERROR "missing return" + +func _() int { + { + print(1) + return 2 + print(3) + } +} // ERROR "missing return" + +func _() int { +L: + { + print(1) + goto L + print(3) + } +} // ERROR "missing return" + +func _() int { + print(1) + { + panic(2) + print(3) + } +} // ERROR "missing return" + +func _() int { + { + print(1) + return 2 + } + print(3) +} // ERROR "missing return" + +func _() int { +L: + { + print(1) + goto L + } + print(3) +} // ERROR "missing return" + +func _() int { + print(1) + { + panic(2) + } + print(3) +} // ERROR "missing return" + +// even an empty dead block triggers the message, because it +// becomes the final statement. + +func _() int { + print(1) + return 2 + {} +} // ERROR "missing return" + +func _() int { +L: + print(1) + goto L + {} +} // ERROR "missing return" + +func _() int { + print(1) + panic(2) + {} +} // ERROR "missing return" + +func _() int { + { + print(1) + return 2 + {} + } +} // ERROR "missing return" + +func _() int { +L: + { + print(1) + goto L + {} + } +} // ERROR "missing return" + +func _() int { + print(1) + { + panic(2) + {} + } +} // ERROR "missing return" + +func _() int { + { + print(1) + return 2 + } + {} +} // ERROR "missing return" + +func _() int { +L: + { + print(1) + goto L + } + {} +} // ERROR "missing return" + +func _() int { + print(1) + { + panic(2) + } + {} +} // ERROR "missing return" + +// if-else chain with final else and all terminating is okay + +func _() int { + print(1) + if x == nil { + panic(2) + } else { + panic(3) + } +} + +func _() int { +L: + print(1) + if x == nil { + panic(2) + } else { + goto L + } +} + +func _() int { +L: + print(1) + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 2 { + panic(3) + } else { + goto L + } +} + +// if-else chain missing final else is not okay, even if the +// conditions cover every possible case. + +func _() int { + print(1) + if x == nil { + panic(2) + } else if x != nil { + panic(3) + } +} // ERROR "missing return" + +func _() int { + print(1) + if x == nil { + panic(2) + } +} // ERROR "missing return" + +func _() int { + print(1) + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 1 { + panic(3) + } +} // ERROR "missing return" + + +// for { loops that never break are okay. + +func _() int { + print(1) + for {} +} + +func _() int { + for { + for { + break + } + } +} + +func _() int { + for { + L: + for { + break L + } + } +} + +// for { loops that break are not okay. + +func _() int { + print(1) + for { break } +} // ERROR "missing return" + +func _() int { + for { + for { + } + break + } +} // ERROR "missing return" + +func _() int { +L: + for { + for { + break L + } + } +} // ERROR "missing return" + +// if there's a condition - even "true" - the loops are no longer syntactically terminating + +func _() int { + print(1) + for x == nil {} +} // ERROR "missing return" + +func _() int { + for x == nil { + for { + break + } + } +} // ERROR "missing return" + +func _() int { + for x == nil { + L: + for { + break L + } + } +} // ERROR "missing return" + +func _() int { + print(1) + for true {} +} // ERROR "missing return" + +func _() int { + for true { + for { + break + } + } +} // ERROR "missing return" + +func _() int { + for true { + L: + for { + break L + } + } +} // ERROR "missing return" + +// select in which all cases terminate and none break are okay. + +func _() int { + print(1) + select{} +} + +func _() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + } +} + +func _() int { + print(1) + select { + case <-c: + print(2) + for{} + } +} + +func _() int { +L: + print(1) + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + goto L + } +} + +func _() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + default: + select{} + } +} + +// if any cases don't terminate, the select isn't okay anymore + +func _() int { + print(1) + select { + case <-c: + print(2) + } +} // ERROR "missing return" + +func _() int { +L: + print(1) + select { + case <-c: + print(2) + panic("abc") + goto L + case c <- 1: + print(2) + } +} // ERROR "missing return" + + +func _() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + default: + print(2) + } +} // ERROR "missing return" + + +// if any breaks refer to the select, the select isn't okay anymore, even if they're dead + +func _() int { + print(1) + select{ default: break } +} // ERROR "missing return" + +func _() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + break + } +} // ERROR "missing return" + +func _() int { + print(1) +L: + select { + case <-c: + print(2) + for{ break L } + } +} // ERROR "missing return" + +func _() int { + print(1) +L: + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + break L + } +} // ERROR "missing return" + +func _() int { + print(1) + select { + case <-c: + print(1) + panic("abc") + default: + select{} + break + } +} // ERROR "missing return" + +// switch with default in which all cases terminate is okay + +func _() int { + print(1) + switch x { + case 1: + print(2) + panic(3) + default: + return 4 + } +} + +func _() int { + print(1) + switch x { + default: + return 4 + case 1: + print(2) + panic(3) + } +} + +func _() int { + print(1) + switch x { + case 1: + print(2) + fallthrough + default: + return 4 + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +func _() int { + print(1) + switch { + } +} // ERROR "missing return" + + +func _() int { + print(1) + switch x { + case 1: + print(2) + panic(3) + case 2: + return 4 + } +} // ERROR "missing return" + +func _() int { + print(1) + switch x { + case 2: + return 4 + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { + print(1) + switch x { + case 1: + print(2) + fallthrough + case 2: + return 4 + } +} // ERROR "missing return" + +func _() int { + print(1) + switch x { + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +func _() int { + print(1) +L: + switch x { + case 1: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +func _() int { + print(1) + switch x { + default: + return 4 + break + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { + print(1) +L: + switch x { + case 1: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +// type switch with default in which all cases terminate is okay + +func _() int { + print(1) + switch x.(type) { + case int: + print(2) + panic(3) + default: + return 4 + } +} + +func _() int { + print(1) + switch x.(type) { + default: + return 4 + case int: + print(2) + panic(3) + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +func _() int { + print(1) + switch { + } +} // ERROR "missing return" + + +func _() int { + print(1) + switch x.(type) { + case int: + print(2) + panic(3) + case float64: + return 4 + } +} // ERROR "missing return" + +func _() int { + print(1) + switch x.(type) { + case float64: + return 4 + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { + print(1) + switch x.(type) { + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +func _() int { + print(1) +L: + switch x.(type) { + case int: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +func _() int { + print(1) + switch x.(type) { + default: + return 4 + break + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { + print(1) +L: + switch x.(type) { + case int: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +// again, but without the leading print(1). +// testing that everything works when the terminating statement is first. + +func _() int { +} // ERROR "missing return" + +// return is okay +func _() int { + return 2 +} + +// goto is okay +func _() int { +L: + goto L +} + +// panic is okay +func _() int { + panic(2) +} + +// but only builtin panic +func _() int { + var panic = func(int) {} + panic(2) +} // ERROR "missing return" + +// block ending in terminating statement is okay +func _() int { + { + return 2 + } +} + +// block ending in terminating statement is okay +func _() int { +L: + { + goto L + } +} + +// block ending in terminating statement is okay +func _() int { + { + panic(2) + } +} + +// adding more code - even though it is dead - now requires a return + +func _() int { + return 2 + print(3) +} // ERROR "missing return" + +func _() int { +L: + goto L + print(3) +} // ERROR "missing return" + +func _() int { + panic(2) + print(3) +} // ERROR "missing return" + +func _() int { + { + return 2 + print(3) + } +} // ERROR "missing return" + +func _() int { +L: + { + goto L + print(3) + } +} // ERROR "missing return" + +func _() int { + { + panic(2) + print(3) + } +} // ERROR "missing return" + +func _() int { + { + return 2 + } + print(3) +} // ERROR "missing return" + +func _() int { +L: + { + goto L + } + print(3) +} // ERROR "missing return" + +func _() int { + { + panic(2) + } + print(3) +} // ERROR "missing return" + +// even an empty dead block triggers the message, because it +// becomes the final statement. + +func _() int { + return 2 + {} +} // ERROR "missing return" + +func _() int { +L: + goto L + {} +} // ERROR "missing return" + +func _() int { + panic(2) + {} +} // ERROR "missing return" + +func _() int { + { + return 2 + {} + } +} // ERROR "missing return" + +func _() int { +L: + { + goto L + {} + } +} // ERROR "missing return" + +func _() int { + { + panic(2) + {} + } +} // ERROR "missing return" + +func _() int { + { + return 2 + } + {} +} // ERROR "missing return" + +func _() int { +L: + { + goto L + } + {} +} // ERROR "missing return" + +func _() int { + { + panic(2) + } + {} +} // ERROR "missing return" + +// if-else chain with final else and all terminating is okay + +func _() int { + if x == nil { + panic(2) + } else { + panic(3) + } +} + +func _() int { +L: + if x == nil { + panic(2) + } else { + goto L + } +} + +func _() int { +L: + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 2 { + panic(3) + } else { + goto L + } +} + +// if-else chain missing final else is not okay, even if the +// conditions cover every possible case. + +func _() int { + if x == nil { + panic(2) + } else if x != nil { + panic(3) + } +} // ERROR "missing return" + +func _() int { + if x == nil { + panic(2) + } +} // ERROR "missing return" + +func _() int { + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 1 { + panic(3) + } +} // ERROR "missing return" + + +// for { loops that never break are okay. + +func _() int { + for {} +} + +func _() int { + for { + for { + break + } + } +} + +func _() int { + for { + L: + for { + break L + } + } +} + +// for { loops that break are not okay. + +func _() int { + for { break } +} // ERROR "missing return" + +func _() int { + for { + for { + } + break + } +} // ERROR "missing return" + +func _() int { +L: + for { + for { + break L + } + } +} // ERROR "missing return" + +// if there's a condition - even "true" - the loops are no longer syntactically terminating + +func _() int { + for x == nil {} +} // ERROR "missing return" + +func _() int { + for x == nil { + for { + break + } + } +} // ERROR "missing return" + +func _() int { + for x == nil { + L: + for { + break L + } + } +} // ERROR "missing return" + +func _() int { + for true {} +} // ERROR "missing return" + +func _() int { + for true { + for { + break + } + } +} // ERROR "missing return" + +func _() int { + for true { + L: + for { + break L + } + } +} // ERROR "missing return" + +// select in which all cases terminate and none break are okay. + +func _() int { + select{} +} + +func _() int { + select { + case <-c: + print(2) + panic("abc") + } +} + +func _() int { + select { + case <-c: + print(2) + for{} + } +} + +func _() int { +L: + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + goto L + } +} + +func _() int { + select { + case <-c: + print(2) + panic("abc") + default: + select{} + } +} + +// if any cases don't terminate, the select isn't okay anymore + +func _() int { + select { + case <-c: + print(2) + } +} // ERROR "missing return" + +func _() int { +L: + select { + case <-c: + print(2) + panic("abc") + goto L + case c <- 1: + print(2) + } +} // ERROR "missing return" + + +func _() int { + select { + case <-c: + print(2) + panic("abc") + default: + print(2) + } +} // ERROR "missing return" + + +// if any breaks refer to the select, the select isn't okay anymore, even if they're dead + +func _() int { + select{ default: break } +} // ERROR "missing return" + +func _() int { + select { + case <-c: + print(2) + panic("abc") + break + } +} // ERROR "missing return" + +func _() int { +L: + select { + case <-c: + print(2) + for{ break L } + } +} // ERROR "missing return" + +func _() int { +L: + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + break L + } +} // ERROR "missing return" + +func _() int { + select { + case <-c: + panic("abc") + default: + select{} + break + } +} // ERROR "missing return" + +// switch with default in which all cases terminate is okay + +func _() int { + switch x { + case 1: + print(2) + panic(3) + default: + return 4 + } +} + +func _() int { + switch x { + default: + return 4 + case 1: + print(2) + panic(3) + } +} + +func _() int { + switch x { + case 1: + print(2) + fallthrough + default: + return 4 + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +func _() int { + switch { + } +} // ERROR "missing return" + + +func _() int { + switch x { + case 1: + print(2) + panic(3) + case 2: + return 4 + } +} // ERROR "missing return" + +func _() int { + switch x { + case 2: + return 4 + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { + switch x { + case 1: + print(2) + fallthrough + case 2: + return 4 + } +} // ERROR "missing return" + +func _() int { + switch x { + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +func _() int { +L: + switch x { + case 1: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +func _() int { + switch x { + default: + return 4 + break + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { +L: + switch x { + case 1: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +// type switch with default in which all cases terminate is okay + +func _() int { + switch x.(type) { + case int: + print(2) + panic(3) + default: + return 4 + } +} + +func _() int { + switch x.(type) { + default: + return 4 + case int: + print(2) + panic(3) + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +func _() int { + switch { + } +} // ERROR "missing return" + + +func _() int { + switch x.(type) { + case int: + print(2) + panic(3) + case float64: + return 4 + } +} // ERROR "missing return" + +func _() int { + switch x.(type) { + case float64: + return 4 + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { + switch x.(type) { + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +func _() int { +L: + switch x.(type) { + case int: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +func _() int { + switch x.(type) { + default: + return 4 + break + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +func _() int { +L: + switch x.(type) { + case int: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +func _() int { + switch x.(type) { + default: + return 4 + case int, float64: + print(2) + panic(3) + } +} + +// again, with func literals + +var _ = func() int { +} // ERROR "missing return" + +var _ = func() int { + print(1) +} // ERROR "missing return" + +// return is okay +var _ = func() int { + print(1) + return 2 +} + +// goto is okay +var _ = func() int { +L: + print(1) + goto L +} + +// panic is okay +var _ = func() int { + print(1) + panic(2) +} + +// but only builtin panic +var _ = func() int { + var panic = func(int) {} + print(1) + panic(2) +} // ERROR "missing return" + +// block ending in terminating statement is okay +var _ = func() int { + { + print(1) + return 2 + } +} + +// block ending in terminating statement is okay +var _ = func() int { +L: + { + print(1) + goto L + } +} + +// block ending in terminating statement is okay +var _ = func() int { + print(1) + { + panic(2) + } +} + +// adding more code - even though it is dead - now requires a return + +var _ = func() int { + print(1) + return 2 + print(3) +} // ERROR "missing return" + +var _ = func() int { +L: + print(1) + goto L + print(3) +} // ERROR "missing return" + +var _ = func() int { + print(1) + panic(2) + print(3) +} // ERROR "missing return" + +var _ = func() int { + { + print(1) + return 2 + print(3) + } +} // ERROR "missing return" + +var _ = func() int { +L: + { + print(1) + goto L + print(3) + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + { + panic(2) + print(3) + } +} // ERROR "missing return" + +var _ = func() int { + { + print(1) + return 2 + } + print(3) +} // ERROR "missing return" + +var _ = func() int { +L: + { + print(1) + goto L + } + print(3) +} // ERROR "missing return" + +var _ = func() int { + print(1) + { + panic(2) + } + print(3) +} // ERROR "missing return" + +// even an empty dead block triggers the message, because it +// becomes the final statement. + +var _ = func() int { + print(1) + return 2 + {} +} // ERROR "missing return" + +var _ = func() int { +L: + print(1) + goto L + {} +} // ERROR "missing return" + +var _ = func() int { + print(1) + panic(2) + {} +} // ERROR "missing return" + +var _ = func() int { + { + print(1) + return 2 + {} + } +} // ERROR "missing return" + +var _ = func() int { +L: + { + print(1) + goto L + {} + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + { + panic(2) + {} + } +} // ERROR "missing return" + +var _ = func() int { + { + print(1) + return 2 + } + {} +} // ERROR "missing return" + +var _ = func() int { +L: + { + print(1) + goto L + } + {} +} // ERROR "missing return" + +var _ = func() int { + print(1) + { + panic(2) + } + {} +} // ERROR "missing return" + +// if-else chain with final else and all terminating is okay + +var _ = func() int { + print(1) + if x == nil { + panic(2) + } else { + panic(3) + } +} + +var _ = func() int { +L: + print(1) + if x == nil { + panic(2) + } else { + goto L + } +} + +var _ = func() int { +L: + print(1) + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 2 { + panic(3) + } else { + goto L + } +} + +// if-else chain missing final else is not okay, even if the +// conditions cover every possible case. + +var _ = func() int { + print(1) + if x == nil { + panic(2) + } else if x != nil { + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + if x == nil { + panic(2) + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 1 { + panic(3) + } +} // ERROR "missing return" + + +// for { loops that never break are okay. + +var _ = func() int { + print(1) + for {} +} + +var _ = func() int { + for { + for { + break + } + } +} + +var _ = func() int { + for { + L: + for { + break L + } + } +} + +// for { loops that break are not okay. + +var _ = func() int { + print(1) + for { break } +} // ERROR "missing return" + +var _ = func() int { + for { + for { + } + break + } +} // ERROR "missing return" + +var _ = func() int { +L: + for { + for { + break L + } + } +} // ERROR "missing return" + +// if there's a condition - even "true" - the loops are no longer syntactically terminating + +var _ = func() int { + print(1) + for x == nil {} +} // ERROR "missing return" + +var _ = func() int { + for x == nil { + for { + break + } + } +} // ERROR "missing return" + +var _ = func() int { + for x == nil { + L: + for { + break L + } + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + for true {} +} // ERROR "missing return" + +var _ = func() int { + for true { + for { + break + } + } +} // ERROR "missing return" + +var _ = func() int { + for true { + L: + for { + break L + } + } +} // ERROR "missing return" + +// select in which all cases terminate and none break are okay. + +var _ = func() int { + print(1) + select{} +} + +var _ = func() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + } +} + +var _ = func() int { + print(1) + select { + case <-c: + print(2) + for{} + } +} + +var _ = func() int { +L: + print(1) + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + goto L + } +} + +var _ = func() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + default: + select{} + } +} + +// if any cases don't terminate, the select isn't okay anymore + +var _ = func() int { + print(1) + select { + case <-c: + print(2) + } +} // ERROR "missing return" + +var _ = func() int { +L: + print(1) + select { + case <-c: + print(2) + panic("abc") + goto L + case c <- 1: + print(2) + } +} // ERROR "missing return" + + +var _ = func() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + default: + print(2) + } +} // ERROR "missing return" + + +// if any breaks refer to the select, the select isn't okay anymore, even if they're dead + +var _ = func() int { + print(1) + select{ default: break } +} // ERROR "missing return" + +var _ = func() int { + print(1) + select { + case <-c: + print(2) + panic("abc") + break + } +} // ERROR "missing return" + +var _ = func() int { + print(1) +L: + select { + case <-c: + print(2) + for{ break L } + } +} // ERROR "missing return" + +var _ = func() int { + print(1) +L: + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + break L + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + select { + case <-c: + print(1) + panic("abc") + default: + select{} + break + } +} // ERROR "missing return" + +// switch with default in which all cases terminate is okay + +var _ = func() int { + print(1) + switch x { + case 1: + print(2) + panic(3) + default: + return 4 + } +} + +var _ = func() int { + print(1) + switch x { + default: + return 4 + case 1: + print(2) + panic(3) + } +} + +var _ = func() int { + print(1) + switch x { + case 1: + print(2) + fallthrough + default: + return 4 + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +var _ = func() int { + print(1) + switch { + } +} // ERROR "missing return" + + +var _ = func() int { + print(1) + switch x { + case 1: + print(2) + panic(3) + case 2: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + switch x { + case 2: + return 4 + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + switch x { + case 1: + print(2) + fallthrough + case 2: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + switch x { + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +var _ = func() int { + print(1) +L: + switch x { + case 1: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + switch x { + default: + return 4 + break + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + print(1) +L: + switch x { + case 1: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +// type switch with default in which all cases terminate is okay + +var _ = func() int { + print(1) + switch x.(type) { + case int: + print(2) + panic(3) + default: + return 4 + } +} + +var _ = func() int { + print(1) + switch x.(type) { + default: + return 4 + case int: + print(2) + panic(3) + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +var _ = func() int { + print(1) + switch { + } +} // ERROR "missing return" + + +var _ = func() int { + print(1) + switch x.(type) { + case int: + print(2) + panic(3) + case float64: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + switch x.(type) { + case float64: + return 4 + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + switch x.(type) { + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +var _ = func() int { + print(1) +L: + switch x.(type) { + case int: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + print(1) + switch x.(type) { + default: + return 4 + break + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + print(1) +L: + switch x.(type) { + case int: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +// again, but without the leading print(1). +// testing that everything works when the terminating statement is first. + +var _ = func() int { +} // ERROR "missing return" + +// return is okay +var _ = func() int { + return 2 +} + +// goto is okay +var _ = func() int { +L: + goto L +} + +// panic is okay +var _ = func() int { + panic(2) +} + +// but only builtin panic +var _ = func() int { + var panic = func(int) {} + panic(2) +} // ERROR "missing return" + +// block ending in terminating statement is okay +var _ = func() int { + { + return 2 + } +} + +// block ending in terminating statement is okay +var _ = func() int { +L: + { + goto L + } +} + +// block ending in terminating statement is okay +var _ = func() int { + { + panic(2) + } +} + +// adding more code - even though it is dead - now requires a return + +var _ = func() int { + return 2 + print(3) +} // ERROR "missing return" + +var _ = func() int { +L: + goto L + print(3) +} // ERROR "missing return" + +var _ = func() int { + panic(2) + print(3) +} // ERROR "missing return" + +var _ = func() int { + { + return 2 + print(3) + } +} // ERROR "missing return" + +var _ = func() int { +L: + { + goto L + print(3) + } +} // ERROR "missing return" + +var _ = func() int { + { + panic(2) + print(3) + } +} // ERROR "missing return" + +var _ = func() int { + { + return 2 + } + print(3) +} // ERROR "missing return" + +var _ = func() int { +L: + { + goto L + } + print(3) +} // ERROR "missing return" + +var _ = func() int { + { + panic(2) + } + print(3) +} // ERROR "missing return" + +// even an empty dead block triggers the message, because it +// becomes the final statement. + +var _ = func() int { + return 2 + {} +} // ERROR "missing return" + +var _ = func() int { +L: + goto L + {} +} // ERROR "missing return" + +var _ = func() int { + panic(2) + {} +} // ERROR "missing return" + +var _ = func() int { + { + return 2 + {} + } +} // ERROR "missing return" + +var _ = func() int { +L: + { + goto L + {} + } +} // ERROR "missing return" + +var _ = func() int { + { + panic(2) + {} + } +} // ERROR "missing return" + +var _ = func() int { + { + return 2 + } + {} +} // ERROR "missing return" + +var _ = func() int { +L: + { + goto L + } + {} +} // ERROR "missing return" + +var _ = func() int { + { + panic(2) + } + {} +} // ERROR "missing return" + +// if-else chain with final else and all terminating is okay + +var _ = func() int { + if x == nil { + panic(2) + } else { + panic(3) + } +} + +var _ = func() int { +L: + if x == nil { + panic(2) + } else { + goto L + } +} + +var _ = func() int { +L: + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 2 { + panic(3) + } else { + goto L + } +} + +// if-else chain missing final else is not okay, even if the +// conditions cover every possible case. + +var _ = func() int { + if x == nil { + panic(2) + } else if x != nil { + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + if x == nil { + panic(2) + } +} // ERROR "missing return" + +var _ = func() int { + if x == nil { + panic(2) + } else if x == 1 { + return 0 + } else if x != 1 { + panic(3) + } +} // ERROR "missing return" + + +// for { loops that never break are okay. + +var _ = func() int { + for {} +} + +var _ = func() int { + for { + for { + break + } + } +} + +var _ = func() int { + for { + L: + for { + break L + } + } +} + +// for { loops that break are not okay. + +var _ = func() int { + for { break } +} // ERROR "missing return" + +var _ = func() int { + for { + for { + } + break + } +} // ERROR "missing return" + +var _ = func() int { +L: + for { + for { + break L + } + } +} // ERROR "missing return" + +// if there's a condition - even "true" - the loops are no longer syntactically terminating + +var _ = func() int { + for x == nil {} +} // ERROR "missing return" + +var _ = func() int { + for x == nil { + for { + break + } + } +} // ERROR "missing return" + +var _ = func() int { + for x == nil { + L: + for { + break L + } + } +} // ERROR "missing return" + +var _ = func() int { + for true {} +} // ERROR "missing return" + +var _ = func() int { + for true { + for { + break + } + } +} // ERROR "missing return" + +var _ = func() int { + for true { + L: + for { + break L + } + } +} // ERROR "missing return" + +// select in which all cases terminate and none break are okay. + +var _ = func() int { + select{} +} + +var _ = func() int { + select { + case <-c: + print(2) + panic("abc") + } +} + +var _ = func() int { + select { + case <-c: + print(2) + for{} + } +} + +var _ = func() int { +L: + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + goto L + } +} + +var _ = func() int { + select { + case <-c: + print(2) + panic("abc") + default: + select{} + } +} + +// if any cases don't terminate, the select isn't okay anymore + +var _ = func() int { + select { + case <-c: + print(2) + } +} // ERROR "missing return" + +var _ = func() int { +L: + select { + case <-c: + print(2) + panic("abc") + goto L + case c <- 1: + print(2) + } +} // ERROR "missing return" + + +var _ = func() int { + select { + case <-c: + print(2) + panic("abc") + default: + print(2) + } +} // ERROR "missing return" + + +// if any breaks refer to the select, the select isn't okay anymore, even if they're dead + +var _ = func() int { + select{ default: break } +} // ERROR "missing return" + +var _ = func() int { + select { + case <-c: + print(2) + panic("abc") + break + } +} // ERROR "missing return" + +var _ = func() int { +L: + select { + case <-c: + print(2) + for{ break L } + } +} // ERROR "missing return" + +var _ = func() int { +L: + select { + case <-c: + print(2) + panic("abc") + case c <- 1: + print(2) + break L + } +} // ERROR "missing return" + +var _ = func() int { + select { + case <-c: + panic("abc") + default: + select{} + break + } +} // ERROR "missing return" + +// switch with default in which all cases terminate is okay + +var _ = func() int { + switch x { + case 1: + print(2) + panic(3) + default: + return 4 + } +} + +var _ = func() int { + switch x { + default: + return 4 + case 1: + print(2) + panic(3) + } +} + +var _ = func() int { + switch x { + case 1: + print(2) + fallthrough + default: + return 4 + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +var _ = func() int { + switch { + } +} // ERROR "missing return" + + +var _ = func() int { + switch x { + case 1: + print(2) + panic(3) + case 2: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + switch x { + case 2: + return 4 + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + switch x { + case 1: + print(2) + fallthrough + case 2: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + switch x { + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +var _ = func() int { +L: + switch x { + case 1: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + switch x { + default: + return 4 + break + case 1: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { +L: + switch x { + case 1: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +// type switch with default in which all cases terminate is okay + +var _ = func() int { + switch x.(type) { + case int: + print(2) + panic(3) + default: + return 4 + } +} + +var _ = func() int { + switch x.(type) { + default: + return 4 + case int: + print(2) + panic(3) + } +} + +// if no default or some case doesn't terminate, switch is no longer okay + +var _ = func() int { + switch { + } +} // ERROR "missing return" + + +var _ = func() int { + switch x.(type) { + case int: + print(2) + panic(3) + case float64: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + switch x.(type) { + case float64: + return 4 + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { + switch x.(type) { + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +// if any breaks refer to the switch, switch is no longer okay + +var _ = func() int { +L: + switch x.(type) { + case int: + print(2) + panic(3) + break L + default: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + switch x.(type) { + default: + return 4 + break + case int: + print(2) + panic(3) + } +} // ERROR "missing return" + +var _ = func() int { +L: + switch x.(type) { + case int: + print(2) + for { + break L + } + default: + return 4 + } +} // ERROR "missing return" + +var _ = func() int { + switch x.(type) { + default: + return 4 + case int, float64: + print(2) + panic(3) + } +} + +/**/ |