mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
cmd/gc: eliminate dead code in switch statements
Ordinary switch statements are rewritten into a sequence of if statements. Staticly dead cases were not being eliminated because the rewrite introduced a temporary, which hid the fact that the case was a constant. Stop doing that. This eliminates dead code in the standard library at: runtime/cgocall.go:219 runtime/cgocall.go:269 debug/gosym/pclntab.go:175 debug/macho/file.go:208 math/big/nat.go:635 math/big/nat.go:850 math/big/nat.go:1058 cmd/pprof/internal/commands/commands.go:86 net/sock_bsd.go:19 cmd/go/build.go:2657 cmd/go/env.go:90 Fixes #9608. Change-Id: Ic23a05dfbb1ad91d5f62a6506b35a13e51b33e38 Reviewed-on: https://go-review.googlesource.com/3980 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
82a761b656
commit
4ce06f4b5c
3 changed files with 94 additions and 4 deletions
|
@ -503,7 +503,7 @@ exprbsw(Case *c0, int ncase, int arg)
|
|||
|
||||
/*
|
||||
* normal (expression) switch.
|
||||
* rebulid case statements into if .. goto
|
||||
* rebuild case statements into if .. goto
|
||||
*/
|
||||
static void
|
||||
exprswitch(Node *sw)
|
||||
|
@ -533,12 +533,15 @@ exprswitch(Node *sw)
|
|||
*/
|
||||
exprname = N;
|
||||
cas = nil;
|
||||
if(arg != Strue && arg != Sfalse) {
|
||||
if(arg == Strue || arg == Sfalse)
|
||||
exprname = nodbool(arg == Strue);
|
||||
else if(consttype(sw->ntest) >= 0)
|
||||
// leave constants to enable dead code elimination (issue 9608)
|
||||
exprname = sw->ntest;
|
||||
else {
|
||||
exprname = temp(sw->ntest->type);
|
||||
cas = list1(nod(OAS, exprname, sw->ntest));
|
||||
typechecklist(cas, Etop);
|
||||
} else {
|
||||
exprname = nodbool(arg == Strue);
|
||||
}
|
||||
|
||||
c0 = mkcaselist(sw, arg);
|
||||
|
|
73
test/fixedbugs/issue9608.dir/issue9608.go
Normal file
73
test/fixedbugs/issue9608.dir/issue9608.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
package main
|
||||
|
||||
func fail() // unimplemented, to test dead code elimination
|
||||
|
||||
// Test dead code elimination in if statements
|
||||
func init() {
|
||||
if false {
|
||||
fail()
|
||||
}
|
||||
if 0 == 1 {
|
||||
fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Test dead code elimination in ordinary switch statements
|
||||
func init() {
|
||||
const x = 0
|
||||
switch x {
|
||||
case 1:
|
||||
fail()
|
||||
}
|
||||
|
||||
switch 1 {
|
||||
case x:
|
||||
fail()
|
||||
}
|
||||
|
||||
switch {
|
||||
case false:
|
||||
fail()
|
||||
}
|
||||
|
||||
const a = "a"
|
||||
switch a {
|
||||
case "b":
|
||||
fail()
|
||||
}
|
||||
|
||||
const snowman = '☃'
|
||||
switch snowman {
|
||||
case '☀':
|
||||
fail()
|
||||
}
|
||||
|
||||
const zero = float64(0.0)
|
||||
const one = float64(1.0)
|
||||
switch one {
|
||||
case -1.0:
|
||||
fail()
|
||||
case zero:
|
||||
fail()
|
||||
}
|
||||
|
||||
switch 1.0i {
|
||||
case 1:
|
||||
fail()
|
||||
case -1i:
|
||||
fail()
|
||||
}
|
||||
|
||||
const no = false
|
||||
switch no {
|
||||
case true:
|
||||
fail()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
}
|
14
test/fixedbugs/issue9608.go
Normal file
14
test/fixedbugs/issue9608.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
// rundir
|
||||
|
||||
// Copyright 2015 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.
|
||||
|
||||
// Issue 9608: dead code elimination in switch statements.
|
||||
|
||||
// This has to be done as a package rather than as a file,
|
||||
// because run.go runs files with 'go run', which passes the
|
||||
// -complete flag to compiler, causing it to complain about
|
||||
// the intentionally unimplemented function fail.
|
||||
|
||||
package ignored
|
Loading…
Reference in a new issue