github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/compile/internal/gc/pgen_test.go (about) 1 // Copyright 2015 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 gc 6 7 import ( 8 "cmd/compile/internal/types" 9 "reflect" 10 "sort" 11 "testing" 12 ) 13 14 func typeWithoutPointers() *types.Type { 15 t := types.New(TSTRUCT) 16 f := &types.Field{Type: types.New(TINT)} 17 t.SetFields([]*types.Field{f}) 18 return t 19 } 20 21 func typeWithPointers() *types.Type { 22 t := types.New(TSTRUCT) 23 f := &types.Field{Type: types.New(TPTR64)} 24 t.SetFields([]*types.Field{f}) 25 return t 26 } 27 28 // Test all code paths for cmpstackvarlt. 29 func TestCmpstackvar(t *testing.T) { 30 testdata := []struct { 31 a, b Node 32 lt bool 33 }{ 34 { 35 Node{Class: PAUTO}, 36 Node{Class: PFUNC}, 37 false, 38 }, 39 { 40 Node{Class: PFUNC}, 41 Node{Class: PAUTO}, 42 true, 43 }, 44 { 45 Node{Class: PFUNC, Xoffset: 0}, 46 Node{Class: PFUNC, Xoffset: 10}, 47 true, 48 }, 49 { 50 Node{Class: PFUNC, Xoffset: 20}, 51 Node{Class: PFUNC, Xoffset: 10}, 52 false, 53 }, 54 { 55 Node{Class: PFUNC, Xoffset: 10}, 56 Node{Class: PFUNC, Xoffset: 10}, 57 false, 58 }, 59 { 60 Node{Class: PPARAM, Xoffset: 10}, 61 Node{Class: PPARAMOUT, Xoffset: 20}, 62 true, 63 }, 64 { 65 Node{Class: PPARAMOUT, Xoffset: 10}, 66 Node{Class: PPARAM, Xoffset: 20}, 67 true, 68 }, 69 { 70 Node{Class: PAUTO, flags: nodeUsed}, 71 Node{Class: PAUTO}, 72 true, 73 }, 74 { 75 Node{Class: PAUTO}, 76 Node{Class: PAUTO, flags: nodeUsed}, 77 false, 78 }, 79 { 80 Node{Class: PAUTO, Type: typeWithoutPointers()}, 81 Node{Class: PAUTO, Type: typeWithPointers()}, 82 false, 83 }, 84 { 85 Node{Class: PAUTO, Type: typeWithPointers()}, 86 Node{Class: PAUTO, Type: typeWithoutPointers()}, 87 true, 88 }, 89 { 90 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}}, 91 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}}, 92 true, 93 }, 94 { 95 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}}, 96 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}}, 97 false, 98 }, 99 { 100 Node{Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}}, 101 Node{Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}}, 102 false, 103 }, 104 { 105 Node{Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}}, 106 Node{Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}}, 107 true, 108 }, 109 { 110 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, 111 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, 112 true, 113 }, 114 { 115 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, 116 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, 117 false, 118 }, 119 { 120 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, 121 Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, 122 false, 123 }, 124 } 125 for _, d := range testdata { 126 got := cmpstackvarlt(&d.a, &d.b) 127 if got != d.lt { 128 t.Errorf("want %#v < %#v", d.a, d.b) 129 } 130 // If we expect a < b to be true, check that b < a is false. 131 if d.lt && cmpstackvarlt(&d.b, &d.a) { 132 t.Errorf("unexpected %#v < %#v", d.b, d.a) 133 } 134 } 135 } 136 137 func TestStackvarSort(t *testing.T) { 138 inp := []*Node{ 139 {Class: PFUNC, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 140 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 141 {Class: PFUNC, Xoffset: 0, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 142 {Class: PFUNC, Xoffset: 10, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 143 {Class: PFUNC, Xoffset: 20, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 144 {Class: PAUTO, flags: nodeUsed, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 145 {Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &types.Sym{}}, 146 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 147 {Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}, Sym: &types.Sym{}}, 148 {Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}, Sym: &types.Sym{}}, 149 {Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}, Sym: &types.Sym{}}, 150 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, 151 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, 152 } 153 want := []*Node{ 154 {Class: PFUNC, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 155 {Class: PFUNC, Xoffset: 0, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 156 {Class: PFUNC, Xoffset: 10, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 157 {Class: PFUNC, Xoffset: 20, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 158 {Class: PAUTO, flags: nodeUsed, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 159 {Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}, Sym: &types.Sym{}}, 160 {Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}, Sym: &types.Sym{}}, 161 {Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}, Sym: &types.Sym{}}, 162 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 163 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, 164 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, 165 {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, 166 {Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &types.Sym{}}, 167 } 168 // haspointers updates Type.Haspointers as a side effect, so 169 // exercise this function on all inputs so that reflect.DeepEqual 170 // doesn't produce false positives. 171 for i := range want { 172 types.Haspointers(want[i].Type) 173 types.Haspointers(inp[i].Type) 174 } 175 176 sort.Sort(byStackVar(inp)) 177 if !reflect.DeepEqual(want, inp) { 178 t.Error("sort failed") 179 for i := range inp { 180 g := inp[i] 181 w := want[i] 182 eq := reflect.DeepEqual(w, g) 183 if !eq { 184 t.Log(i, w, g) 185 } 186 } 187 } 188 }