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  }