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  }