diff options
author | Keith Randall <khr@golang.org> | 2018-11-06 10:16:17 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2018-11-21 00:49:09 +0000 |
commit | c92a20818bb1b49911c2a23a0bafd5e34c4f7f7c (patch) | |
tree | a4deb92a57fb2f9131c7369edb45c1b9e4464ba5 | |
parent | e602388f98e174895e9adb5f2516b38dc692d45d (diff) | |
download | go-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.go | 12 | ||||
-rw-r--r-- | test/fixedbugs/issue28616.go | 25 |
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: +} |