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