From 95a4f793c077ab7b13fdb7505b65ff19a97a07f9 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 6 Nov 2018 10:16:17 -0800 Subject: [PATCH] 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 #28616 Change-Id: I6680465134e3486dcb658896f5172606cc51b104 Reviewed-on: https://go-review.googlesource.com/c/147817 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick Reviewed-by: Iskander Sharipov --- src/cmd/compile/internal/gc/typecheck.go | 12 +++++++++++- test/fixedbugs/issue28616.go | 25 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue28616.go diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 06dd176b37..8ec60cbbba 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -4084,6 +4084,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. @@ -4106,10 +4112,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: +}