A fallthrough statement can be a labeled fallthrough per Go spec.
However, the hasFallthrough function is not considering this case,
causing mis-compilation.
Fixing this by un-wrapping (possible nested) labeled fallthrough
statements if any.
Fixes #70173
Change-Id: Ic93d4fb75ff02703a32dfc63c3e84a8b7f78c261
Reviewed-on: https://go-review.googlesource.com/c/go/+/624717
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Youlin Feng <fengyoulin@live.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
// hasFallthrough reports whether stmts ends in a fallthrough
// statement.
func hasFallthrough(stmts []syntax.Stmt) bool {
- last, ok := lastNonEmptyStmt(stmts).(*syntax.BranchStmt)
+ // From spec: the last non-empty statement may be a (possibly labeled) "fallthrough" statement
+ // Stripping (possible nested) labeled statement if any.
+ stmt := lastNonEmptyStmt(stmts)
+ for {
+ ls, ok := stmt.(*syntax.LabeledStmt)
+ if !ok {
+ break
+ }
+ stmt = ls.Stmt
+ }
+ last, ok := stmt.(*syntax.BranchStmt)
return ok && last.Tok == syntax.Fallthrough
}
--- /dev/null
+go run main.go
+! stdout .
+! stderr .
+
+-- main.go --
+
+package main
+
+func main() {
+ switch {
+ case true:
+ _:
+ fallthrough
+ default:
+ }
+ switch {
+ case true:
+ _:
+ _:
+ fallthrough
+ default:
+ }
+}