]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix mis-compilation with labeled fallthrough
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sun, 3 Nov 2024 14:27:00 +0000 (21:27 +0700)
committerGopher Robot <gobot@golang.org>
Mon, 4 Nov 2024 16:54:28 +0000 (16:54 +0000)
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>

src/cmd/compile/internal/noder/writer.go
src/cmd/compile/testdata/script/issue70173.txt [new file with mode: 0644]

index 564087d9123868a3adba485bad2a490ce01c6950..f4b02f279dd5f2eaaef14f414cc43e9f6385e065 100644 (file)
@@ -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
 }
 
diff --git a/src/cmd/compile/testdata/script/issue70173.txt b/src/cmd/compile/testdata/script/issue70173.txt
new file mode 100644 (file)
index 0000000..20d4b4f
--- /dev/null
@@ -0,0 +1,23 @@
+go run main.go
+! stdout .
+! stderr .
+
+-- main.go --
+
+package main
+
+func main() {
+       switch {
+       case true:
+       _:
+               fallthrough
+       default:
+       }
+       switch {
+       case true:
+       _:
+       _:
+               fallthrough
+       default:
+       }
+}