1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 const src = `package main
34 if true { // even known values are ignored
37 for true { // even known values are ignored
60 func f4(ch chan int) {
72 func f5(unknown bool) {
83 func f6(unknown bool) {
108 func f9(ch chan int) {
116 func f10(ch chan int) {
127 goto; // mustn't crash
133 func TestDeadCode(t *testing.T) {
134 // We'll use dead code detection to verify the CFG.
136 fset := token.NewFileSet()
137 f, err := parser.ParseFile(fset, "dummy.go", src, parser.Mode(0))
141 for _, decl := range f.Decls {
142 if decl, ok := decl.(*ast.FuncDecl); ok {
143 g := New(decl.Body, mayReturn)
145 // Print statements in unreachable blocks
146 // (in order determined by builder).
148 for _, b := range g.Blocks {
150 for _, n := range b.Nodes {
151 fmt.Fprintf(&buf, "\t%s\n", formatNode(fset, n))
156 // Check that the result contains "dead" at least once but not "live".
157 if !bytes.Contains(buf.Bytes(), []byte("dead")) ||
158 bytes.Contains(buf.Bytes(), []byte("live")) {
159 t.Errorf("unexpected dead statements in function %s:\n%s",
162 t.Logf("control flow graph:\n%s", g.Format(fset))
168 // A trivial mayReturn predicate that looks only at syntax, not types.
169 func mayReturn(call *ast.CallExpr) bool {
170 switch fun := call.Fun.(type) {
172 return fun.Name != "panic"
173 case *ast.SelectorExpr:
174 return fun.Sel.Name != "Fatal"