aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2024-11-03 21:27:00 +0700
committerGopher Robot <gobot@golang.org>2024-11-04 16:54:28 +0000
commitea38fa534559d1c25e629d0b1e96a730fa96780b (patch)
treee2bf710af8f27a1876810fe41e94ac38df4d2445 /src/cmd/compile/internal/noder
parent324f41b748fd87ad4a1cafa458bac3014f2fb5f2 (diff)
downloadgo-ea38fa534559d1c25e629d0b1e96a730fa96780b.tar.xz
cmd/compile: fix mis-compilation with labeled fallthrough
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>
Diffstat (limited to 'src/cmd/compile/internal/noder')
-rw-r--r--src/cmd/compile/internal/noder/writer.go12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go
index 564087d912..f4b02f279d 100644
--- a/src/cmd/compile/internal/noder/writer.go
+++ b/src/cmd/compile/internal/noder/writer.go
@@ -3070,7 +3070,17 @@ func isPtrTo(from, to types2.Type) bool {
// 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
}