diff options
| author | Cuong Manh Le <cuong.manhle.vn@gmail.com> | 2024-11-03 21:27:00 +0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-11-04 16:54:28 +0000 |
| commit | ea38fa534559d1c25e629d0b1e96a730fa96780b (patch) | |
| tree | e2bf710af8f27a1876810fe41e94ac38df4d2445 /src/cmd/compile/internal/noder | |
| parent | 324f41b748fd87ad4a1cafa458bac3014f2fb5f2 (diff) | |
| download | go-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.go | 12 |
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 } |
