github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/cmd/newlink/dead_test.go (about) 1 // Copyright 2014 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. 4 5 package main 6 7 import ( 8 "cmd/internal/goobj" 9 "reflect" 10 "strings" 11 "testing" 12 ) 13 14 // Each test case is an object file, generated from a corresponding .s file. 15 // The symbols in the object file with a dead_ prefix are the ones that 16 // should be removed from the program. 17 var deadTests = []string{ 18 "testdata/dead.6", 19 } 20 21 func TestDead(t *testing.T) { 22 for _, obj := range deadTests { 23 p := Prog{GOOS: "darwin", GOARCH: "amd64", StartSym: "start"} 24 p.omitRuntime = true 25 p.Error = func(s string) { t.Error(s) } 26 p.init() 27 p.scan(obj) 28 if p.NumError > 0 { 29 continue // already reported 30 } 31 origSyms := copyMap(p.Syms) 32 origMissing := copyMap(p.Missing) 33 origSymOrder := copySlice(p.SymOrder) 34 origPkgSyms := copySlice(p.Packages["main"].Syms) 35 p.dead() 36 checkDeadMap(t, obj, "p.Syms", origSyms, p.Syms) 37 checkDeadMap(t, obj, "p.Missing", origMissing, p.Missing) 38 checkDeadSlice(t, obj, "p.SymOrder", origSymOrder, p.SymOrder) 39 checkDeadSlice(t, obj, `p.Packages["main"].Syms`, origPkgSyms, p.Packages["main"].Syms) 40 } 41 } 42 43 func copyMap(m interface{}) interface{} { 44 v := reflect.ValueOf(m) 45 out := reflect.MakeMap(v.Type()) 46 for _, key := range v.MapKeys() { 47 out.SetMapIndex(key, v.MapIndex(key)) 48 } 49 return out.Interface() 50 } 51 52 func checkDeadMap(t *testing.T, obj, name string, old, new interface{}) { 53 vold := reflect.ValueOf(old) 54 vnew := reflect.ValueOf(new) 55 for _, vid := range vold.MapKeys() { 56 id := vid.Interface().(goobj.SymID) 57 if strings.HasPrefix(id.Name, "dead_") { 58 if vnew.MapIndex(vid).IsValid() { 59 t.Errorf("%s: %s contains unnecessary symbol %s", obj, name, id) 60 } 61 } else { 62 if !vnew.MapIndex(vid).IsValid() { 63 t.Errorf("%s: %s is missing symbol %s", obj, name, id) 64 } 65 } 66 } 67 for _, vid := range vnew.MapKeys() { 68 id := vid.Interface().(goobj.SymID) 69 if !vold.MapIndex(vid).IsValid() { 70 t.Errorf("%s: %s contains unexpected symbol %s", obj, name, id) 71 } 72 } 73 } 74 75 func copySlice(x []*Sym) (out []*Sym) { 76 return append(out, x...) 77 } 78 79 func checkDeadSlice(t *testing.T, obj, name string, old, new []*Sym) { 80 for i, s := range old { 81 if strings.HasPrefix(s.Name, "dead_") { 82 continue 83 } 84 if len(new) == 0 { 85 t.Errorf("%s: %s is missing symbol %s\nhave%v\nwant%v", obj, name, s, new, old[i:]) 86 return 87 } 88 if new[0].SymID != s.SymID { 89 t.Errorf("%s: %s is incorrect: have %s, want %s\nhave%v\nwant%v", obj, name, new[0].SymID, s.SymID, new, old[i:]) 90 return 91 } 92 new = new[1:] 93 } 94 if len(new) > 0 { 95 t.Errorf("%s: %s has unexpected symbols: %v", obj, name, new) 96 } 97 }