]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.11] cmd/compile: don't deadcode eliminate labels
authorKeith Randall <khr@golang.org>
Tue, 6 Nov 2018 18:16:17 +0000 (10:16 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 21 Nov 2018 00:49:09 +0000 (00:49 +0000)
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

src/cmd/compile/internal/gc/typecheck.go
test/fixedbugs/issue28616.go [new file with mode: 0644]

index bf7090518c85123b4ae15ef16434c93c035ca5cb..3919fbcecb21d49517a3fd8a197c14aac2d33946 100644 (file)
@@ -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 (file)
index 0000000..f1ba974
--- /dev/null
@@ -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:
+}