aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2018-11-06 10:16:17 -0800
committerIan Lance Taylor <iant@golang.org>2018-11-21 00:49:09 +0000
commitc92a20818bb1b49911c2a23a0bafd5e34c4f7f7c (patch)
treea4deb92a57fb2f9131c7369edb45c1b9e4464ba5
parente602388f98e174895e9adb5f2516b38dc692d45d (diff)
downloadgo-c92a20818bb1b49911c2a23a0bafd5e34c4f7f7c.tar.gz
go-c92a20818bb1b49911c2a23a0bafd5e34c4f7f7c.zip
[release-branch.go1.11] cmd/compile: don't deadcode eliminate labels
Dead-code eliminating labels is tricky because there might be gotos that can still reach them. Bug probably introduced with CL 91056 Fixes #28617 Change-Id: I6680465134e3486dcb658896f5172606cc51b104 Reviewed-on: https://go-review.googlesource.com/c/147817 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Iskander Sharipov <iskander.sharipov@intel.com> Reviewed-on: https://go-review.googlesource.com/c/147857
-rw-r--r--src/cmd/compile/internal/gc/typecheck.go12
-rw-r--r--test/fixedbugs/issue28616.go25
2 files changed, 36 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index bf7090518c..3919fbcecb 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -3987,6 +3987,12 @@ func deadcode(fn *Node) {
}
func deadcodeslice(nn Nodes) {
+ var lastLabel = -1
+ for i, n := range nn.Slice() {
+ if n != nil && n.Op == OLABEL {
+ lastLabel = i
+ }
+ }
for i, n := range nn.Slice() {
// Cut is set to true when all nodes after i'th position
// should be removed.
@@ -4009,10 +4015,14 @@ func deadcodeslice(nn Nodes) {
// If "then" or "else" branch ends with panic or return statement,
// it is safe to remove all statements after this node.
// isterminating is not used to avoid goto-related complications.
+ // We must be careful not to deadcode-remove labels, as they
+ // might be the target of a goto. See issue 28616.
if body := body.Slice(); len(body) != 0 {
switch body[(len(body) - 1)].Op {
case ORETURN, ORETJMP, OPANIC:
- cut = true
+ if i > lastLabel {
+ cut = true
+ }
}
}
}
diff --git a/test/fixedbugs/issue28616.go b/test/fixedbugs/issue28616.go
new file mode 100644
index 0000000000..f1ba974797
--- /dev/null
+++ b/test/fixedbugs/issue28616.go
@@ -0,0 +1,25 @@
+// compile
+
+// Copyright 2018 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.
+
+// Make sure we don't dead code eliminate a label.
+
+package p
+
+var i int
+
+func f() {
+
+ if true {
+
+ if i == 1 {
+ goto label
+ }
+
+ return
+ }
+
+label:
+}