mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
![Tyler Bunnell](/assets/img/avatar_default.png)
Small change to cmd/gc to catch a "fallthrough" in the final case of a switch. R=golang-dev, rsc, mtj CC=golang-dev https://golang.org/cl/7841043
404 lines
6.1 KiB
Go
404 lines
6.1 KiB
Go
// run
|
|
|
|
// Copyright 2009 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 switch statements.
|
|
|
|
package main
|
|
|
|
import "os"
|
|
|
|
func assert(cond bool, msg string) {
|
|
if !cond {
|
|
print("assertion fail: ", msg, "\n")
|
|
panic(1)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
i5 := 5
|
|
i7 := 7
|
|
hello := "hello"
|
|
|
|
switch true {
|
|
case i5 < 5:
|
|
assert(false, "<")
|
|
case i5 == 5:
|
|
assert(true, "!")
|
|
case i5 > 5:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch {
|
|
case i5 < 5:
|
|
assert(false, "<")
|
|
case i5 == 5:
|
|
assert(true, "!")
|
|
case i5 > 5:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch x := 5; true {
|
|
case i5 < x:
|
|
assert(false, "<")
|
|
case i5 == x:
|
|
assert(true, "!")
|
|
case i5 > x:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch x := 5; true {
|
|
case i5 < x:
|
|
assert(false, "<")
|
|
case i5 == x:
|
|
assert(true, "!")
|
|
case i5 > x:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0:
|
|
assert(false, "0")
|
|
case 1:
|
|
assert(false, "1")
|
|
case 2:
|
|
assert(false, "2")
|
|
case 3:
|
|
assert(false, "3")
|
|
case 4:
|
|
assert(false, "4")
|
|
case 5:
|
|
assert(true, "5")
|
|
case 6:
|
|
assert(false, "6")
|
|
case 7:
|
|
assert(false, "7")
|
|
case 8:
|
|
assert(false, "8")
|
|
case 9:
|
|
assert(false, "9")
|
|
default:
|
|
assert(false, "default")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0, 1, 2, 3, 4:
|
|
assert(false, "4")
|
|
case 5:
|
|
assert(true, "5")
|
|
case 6, 7, 8, 9:
|
|
assert(false, "9")
|
|
default:
|
|
assert(false, "default")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
assert(false, "4")
|
|
case 5:
|
|
assert(true, "5")
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
default:
|
|
assert(i5 == 5, "good")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 1:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 2:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 3:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 4:
|
|
dummy := 0
|
|
_ = dummy
|
|
assert(false, "4")
|
|
case 5:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 6:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 7:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 8:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 9:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
default:
|
|
dummy := 0
|
|
_ = dummy
|
|
assert(i5 == 5, "good")
|
|
}
|
|
|
|
fired := false
|
|
switch i5 {
|
|
case 0:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough // tests scoping of cases
|
|
case 1:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 2:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 3:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 4:
|
|
dummy := 0
|
|
_ = dummy
|
|
assert(false, "4")
|
|
case 5:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 6:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 7:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 8:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 9:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
default:
|
|
dummy := 0
|
|
_ = dummy
|
|
fired = !fired
|
|
assert(i5 == 5, "good")
|
|
}
|
|
assert(fired, "fired")
|
|
|
|
count := 0
|
|
switch i5 {
|
|
case 0:
|
|
count = count + 1
|
|
fallthrough
|
|
case 1:
|
|
count = count + 1
|
|
fallthrough
|
|
case 2:
|
|
count = count + 1
|
|
fallthrough
|
|
case 3:
|
|
count = count + 1
|
|
fallthrough
|
|
case 4:
|
|
count = count + 1
|
|
assert(false, "4")
|
|
case 5:
|
|
count = count + 1
|
|
fallthrough
|
|
case 6:
|
|
count = count + 1
|
|
fallthrough
|
|
case 7:
|
|
count = count + 1
|
|
fallthrough
|
|
case 8:
|
|
count = count + 1
|
|
fallthrough
|
|
case 9:
|
|
count = count + 1
|
|
fallthrough
|
|
default:
|
|
assert(i5 == count, "good")
|
|
}
|
|
assert(fired, "fired")
|
|
|
|
switch hello {
|
|
case "wowie":
|
|
assert(false, "wowie")
|
|
case "hello":
|
|
assert(true, "hello")
|
|
case "jumpn":
|
|
assert(false, "jumpn")
|
|
default:
|
|
assert(false, "default")
|
|
}
|
|
|
|
fired = false
|
|
switch i := i5 + 2; i {
|
|
case i7:
|
|
fired = true
|
|
default:
|
|
assert(false, "fail")
|
|
}
|
|
assert(fired, "var")
|
|
|
|
// switch on nil-only comparison types
|
|
switch f := func() {}; f {
|
|
case nil:
|
|
assert(false, "f should not be nil")
|
|
default:
|
|
}
|
|
|
|
switch m := make(map[int]int); m {
|
|
case nil:
|
|
assert(false, "m should not be nil")
|
|
default:
|
|
}
|
|
|
|
switch a := make([]int, 1); a {
|
|
case nil:
|
|
assert(false, "m should not be nil")
|
|
default:
|
|
}
|
|
|
|
// switch on interface.
|
|
switch i := interface{}("hello"); i {
|
|
case 42:
|
|
assert(false, `i should be "hello"`)
|
|
case "hello":
|
|
assert(true, "hello")
|
|
default:
|
|
assert(false, `i should be "hello"`)
|
|
}
|
|
|
|
// switch on implicit bool converted to interface
|
|
// was broken: see issue 3980
|
|
switch i := interface{}(true); {
|
|
case i:
|
|
assert(true, "true")
|
|
case false:
|
|
assert(false, "i should be true")
|
|
default:
|
|
assert(false, "i should be true")
|
|
}
|
|
|
|
// switch on interface with constant cases differing by type.
|
|
// was rejected by compiler: see issue 4781
|
|
type T int
|
|
type B bool
|
|
type F float64
|
|
type S string
|
|
switch i := interface{}(float64(1.0)); i {
|
|
case nil:
|
|
assert(false, "i should be float64(1.0)")
|
|
case (*int)(nil):
|
|
assert(false, "i should be float64(1.0)")
|
|
case 1:
|
|
assert(false, "i should be float64(1.0)")
|
|
case T(1):
|
|
assert(false, "i should be float64(1.0)")
|
|
case F(1.0):
|
|
assert(false, "i should be float64(1.0)")
|
|
case 1.0:
|
|
assert(true, "true")
|
|
case "hello":
|
|
assert(false, "i should be float64(1.0)")
|
|
case S("hello"):
|
|
assert(false, "i should be float64(1.0)")
|
|
case true, B(false):
|
|
assert(false, "i should be float64(1.0)")
|
|
case false, B(true):
|
|
assert(false, "i should be float64(1.0)")
|
|
}
|
|
|
|
// switch on array.
|
|
switch ar := [3]int{1, 2, 3}; ar {
|
|
case [3]int{1, 2, 3}:
|
|
assert(true, "[1 2 3]")
|
|
case [3]int{4, 5, 6}:
|
|
assert(false, "ar should be [1 2 3]")
|
|
default:
|
|
assert(false, "ar should be [1 2 3]")
|
|
}
|
|
|
|
// switch on channel
|
|
switch c1, c2 := make(chan int), make(chan int); c1 {
|
|
case nil:
|
|
assert(false, "c1 did not match itself")
|
|
case c2:
|
|
assert(false, "c1 did not match itself")
|
|
case c1:
|
|
assert(true, "chan")
|
|
default:
|
|
assert(false, "c1 did not match itself")
|
|
}
|
|
|
|
// empty switch
|
|
switch {
|
|
}
|
|
|
|
// empty switch with default case.
|
|
fired = false
|
|
switch {
|
|
default:
|
|
fired = true
|
|
}
|
|
assert(fired, "fail")
|
|
|
|
// Default and fallthrough.
|
|
count = 0
|
|
switch {
|
|
default:
|
|
count++
|
|
fallthrough
|
|
case false:
|
|
count++
|
|
}
|
|
assert(count == 2, "fail")
|
|
|
|
// fallthrough to default, which is not at end.
|
|
count = 0
|
|
switch i5 {
|
|
case 5:
|
|
count++
|
|
fallthrough
|
|
default:
|
|
count++
|
|
case 6:
|
|
count++
|
|
}
|
|
assert(count == 2, "fail")
|
|
|
|
i := 0
|
|
switch x := 5; {
|
|
case i < x:
|
|
os.Exit(0)
|
|
case i == x:
|
|
case i > x:
|
|
os.Exit(1)
|
|
}
|
|
}
|